回溯方法
class Solution {
int res = 0;
public int change(int amount, int[] coins) {
int sum = 0;
backTracking(sum,amount,coins,0);
return res;
}
public void backTracking(int sum,int target,int[] coins,int sta) {
if(sum>target)
return;
if(sum == target){
res++;
return;
}
for (int i = sta; i < coins.length; i++) {
sum+=coins[i];
backTracking(sum,target,coins,i);
sum-=coins[i];
}
}
}
动态规划方法
class Solution {
public int change(int amount, int[] coins) {
int[][] dp = new int[coins.length+1][amount+1];
for(int i = 0;i<coins.length+1;i++){
dp[i][0] = 1;
}
for(int i = 1;i<=coins.length;i++){
for(int j = 1;j<amount+1;j++){
if(j<coins[i-1])
dp[i][j] = dp[i-1][j];
else
dp[i][j] = dp[i-1][j]+dp[i][j-coins[i-1]];
}
}
return dp[coins.length][amount];
}
}
回溯法
class Solution {
int res = 0;
public int combinationSum4(int[] nums, int target) {
backTracking(nums,target,0);
return res;
}
public void backTracking(int[] nums,int target,int sum){
if(sum>target)
return;
if(sum == target){
res++;
return;
}
for(int i = 0;i<nums.length;i++){
sum+=nums[i];
backTracking(nums,target,sum);
sum-=nums[i];
}
}
}
动态规划
如果求组合的话外层for 循环遍历物品,内层for 循环遍历背包;如果是求排列的话,外层for 循环遍历背包,内层for 循环遍历物品。
class Solution {
public static int combinationSum4(int[] nums, int target) {
Arrays.sort(nums);
int[][] dp = new int[target + 1][nums.length + 1];
for (int i = 0; i <= nums.length; i++) {
dp[0][i] = 1;
}
for (int i = 1; i <= target; i++) {
for (int j = 1; j <= nums.length; j++) {
if (i < nums[j - 1]) {
dp[i][j] = dp[i][j - 1];
} else {
for (int k = 0; k < j; k++) {
dp[i][j] += dp[i - nums[k]][j];
}
}
}
}
return dp[target][nums.length];
}
}