算法笔记|Day33动态规划VI
☆☆☆☆☆leetcode 322. 零钱兑换
题目链接:leetcode 322. 零钱兑换
题目分析
1.dp数组含义:dp[j]表示凑足总额为j所需钱币的最少个数;
2.递推公式:dp[j]=Math.min(dp[j],dp[j-coins[i]]+1)(分别考虑取第i个钱币与不取第i个钱币得到的钱币个数取最小值);
3.初始化:dp[0]=0,其余dp[]=Integer.MAX_VALUE(凑足总额为j所需钱币的最少个数为0,为了不影响后续计算应赋其他值为最大值Integer.MAX_VALUE);
4.遍历顺序:顺序不影响结果(考虑排列或组合均可),先遍历货币或者背包都可以,背包一定是要正序遍历。
代码
class Solution {
public int coinChange(int[] coins, int amount) {
int dp[]=new int[amount+1];
for(int i=1;i<dp.length;i++)
dp[i]=Integer.MAX_VALUE;
for(int i=0;i<coins.length;i++){
for(int j=coins[i];j<=amount;j++){
if(dp[j-coins[i]]!=Integer.MAX_VALUE)
dp[j]=Math.min(dp[j],dp[j-coins[i]]+1);
}
}
return dp[amount]==Integer.MAX_VALUE?-1:dp[amount];
}
}
☆☆☆☆☆leetcode 279.完全平方数
题目链接:leetcode 279.完全平方数
题目分析
1.dp数组含义:dp[j]表示和为j的完全平方数的最少数量;
2.递推公式:dp[j]=Math.min(dp[j-i*i]+1,dp[j])(分别考虑取i的平方与不取i的平方得到的总个数取最小值);
3.初始化:dp[0]=0,其余dp[]=Integer.MAX_VALUE(为了不影响后续计算应赋dp[0]=0,其他值为最大值Integer.MAX_VALUE);
4.遍历顺序:顺序不影响结果(考虑排列或组合均可),先遍历货币或者背包都可以,背包一定是要正序遍历。
代码
class Solution {
public int numSquares(int n) {
int dp[]=new int[n+1];
for(int i=1;i<=n;i++)
dp[i]=Integer.MAX_VALUE;
for(int i=1;i<=n;i++){
for(int j=i*i;j<=n;j++){
dp[j]=Math.min(dp[j-i*i]+1,dp[j]);
}
}
return dp[n];
}
}
☆☆☆☆☆leetcode 139.单词拆分
题目链接:leetcode 139.单词拆分
题目分析
1.dp数组含义:dp[j]表示字符串长度为j时能否拆分为一个或多个在字典中出现的单词;
2.递推公式:if(set.contains(s.substring(j,i))&&dp[j])dp[i]=true(如果[j,i]区间的子串出现在字典里且dp[j]是true,则dp[i]=true);
3.初始化:dp[0]=true,其余dp[]=false(为了不影响后续计算应赋dp[0]=true,其他值为false);
4.遍历顺序:顺序不影响结果(考虑排列或组合均可),先遍历字符串或者字典都可以。
代码
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
HashSet<String> set=new HashSet<>(wordDict);
boolean dp[]=new boolean[s.length()+1];
dp[0]=true;
for(int i=1;i<=s.length();i++){
for(int j=0;j<i;j++){
if(set.contains(s.substring(j,i))&&dp[j])
dp[i]=true;
}
}
return dp[s.length()];
}
}