算法 day 38
零钱兑换
感觉好起来了,这道题总算是对完全背包相关的内容熟悉一点了...又回去看了20多分钟的上一道零钱兑换,连带这次的转移方程什么的也明白了。不过感觉是短期理解记忆,明天继续看。
class Solution {
public:int coinChange(vector<int>& coins, int amount) {// dp[i] 表示凑成金额i所需的最少硬币数vector<int> dp(amount + 1, amount + 1); // 初始化为一个不可能的大值dp[0] = 0; // 金额0需要0个硬币for (int i = 0; i < coins.size(); i++) { // 遍历硬币for (int j = coins[i]; j <= amount; j++) { // 遍历金额// 状态转移:选择当前硬币或不选择当前硬币dp[j] = min(dp[j], dp[j - coins[i]] + 1);}}// 如果dp[amount]还是初始值,说明无法凑成return dp[amount] > amount ? -1 : dp[amount];}
};完全平方数
感觉好起来了。状态转移方程忘记加1了,搞得输出不对,de了半天,找朋友聊完天豁然开朗。(聊的是闲)也许换个思维或者重新开始忘掉之前的思维定势会好很多。
class Solution {
public:int numSquares(int n) {vector<int> dp(n+1,INT_MAX);dp[0]=0;for(int i =0;i<=n;i++){for(int j=1;j*j<=i;j++){dp[i]=min(dp[i],dp[i-j*j]+1);}}return dp[n];}
};单词拆分
字符串的很多操作都很不熟,这里面也没想到用set,哈希的底子都太弱了。一旦没有那种像本题的完全背包明示,就会很难串联起来之前练过的知识点,说到底来还是熟练度问题,再加上一刷,这都是不可避免的。做好复盘,留下记录,下次再战。
class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {unordered_set<string> wordSet(wordDict.begin(), wordDict.end());vector<bool> dp(s.size() + 1, false);dp[0] = true;for (int i = 1; i <= s.size(); i++) { // 遍历背包for (int j = 0; j < i; j++) { // 遍历物品string word = s.substr(j, i - j); //substr(起始位置,截取的个数)if (wordSet.find(word) != wordSet.end() && dp[j]) {dp[i] = true;}}}return dp[s.size()];}
};