思路:类似于爬楼梯问题。楼梯的阶数一共为target,一次可以走的步数为nums[i]。 一共有多少种走法?
爬楼梯问题,target在外层。
也可以看成 完全背包问题,即数组中的元素可重复使用。技巧是 nums放在外循环,target在内循环。且内循环正序。
但是如果组合问题需考虑元素之间的顺序,需将 target放在外循环,将nums放在内循环。
class Solution { /** * 举一个具体的例子:nums=[1, 3, 4], target=7; * dp[7] = dp[6] + dp[4] + dp[3] * 即:7 的组合数可以由三部分组成,1 和 dp[6],3 和 dp[4], 4 和dp[3]; */ public int combinationSum4(int[] nums, int target) { // dp[i] 表示 和为 i 的组合的个数 int[] dp = new int[target + 1]; dp[0] = 1; // 很关键,它表示如果nums里有一个数 恰好等于target,为1种可能。 for (int i = 1; i <= target; i++) { for (int j = 0; j < nums.length; j++) { if (i >= nums[j]){ dp[i] += dp[i-nums[j]]; } } } return dp[target]; } }