题目:

解法:


思路:
一、读题
- 同一个数字可以无限重复选;
- 找出所有不同组合,组合顺序不算区别:【2,3】 和 【
3,2]】算同一个,不能重复; - 保证答案数量 <150,不用担心结果爆炸。
- 可重复选取 → 回溯的时候,下一层还可以从当前这个下标继续选(不是 i+1)
组合不看顺序 → 为了避免 【2,3】、【3,2】这种重复答案,我们强制只能往后选,不能回头选前面的数字。
举例:选了下标 0 的 2,下一轮还可以选下标 0;但选到下标 1 的 3 之后,就不能回头再选下标 0 的 2。天然消除排列重复。
二、回溯
尝试选当前数字,递归往下走;递归回来撤销选择(回溯),尝试下一个数字。
三、
start:本次只能从start下标开始选,防止回头造成重复组合sum:当前已经累加的总和path:保存当前这条路径选中的数字(临时数组)candidates:原数组target:目标和returnSize:返回答案行数returnColumnSizes:每一行答案的长度res:存放最终所有组合的二维数组
递归终止条件
sum == target:找到一组答案,把 path 拷贝存入 res,return;sum > target:和超了,直接 return(剪枝,不用继续往下搜)
递归逻辑
循环 i 从 start 到数组末尾:
1、sum + candidates i <= target:才继续递归(剪枝优化)
2、把 candidates i 加入 path
3、递归调用:i 不变!因为可以重复选当前元素(重点!和组合 II 区分)
4、递归返回,回溯:删掉 path 末尾元素,尝试下一个 i