1、条件解读
- 数字是可以被重复选择来进行组合的
- 数字可以单独是本身的组合
- candidate 中的每个元素都是独一无二的
- 1 <= target <= 500
- 1 <= candidates.length <= 30
- 1 <= candidates[i] <= 200
2、初步解读的处理
判断元素与目标值的大小,由于元素大于零,适当的处理三种情况
- 小于目标值:不符合条件,但后续还会用到
- 大于目标值:不符合条件,且后续再也不会用到
- 等于目标值:符合条件,且后续不会再用到
3、小于目标值数字处理
这里就到了一个组合的场景了,大致会有一下几种情况
- 单个元素重复拼合
- 多个不同的元素拼合
- 有部分重复元素与其他部分或非重复元素拼合
4、查找方案
单次遍历会引申出多个遍历,需要确保运行没有遗漏也没有重复
方案:
-
为了使得单次查找有效性提高,可以将有效元素的数组先进行排序
-
由于元素会不断的前后遍历,前面部分在遍历后,后面部分无需再和前面部分拼装,避免重复
-
如何开始查找? 从单个数字开始,而后下级以最小的开始多级遍历,如:第一组查找为多个最小数组的组合
-
单个数字查找到何种程度结束遍历? 正常结束:下级所有元素都遍历完,则单个数字结束 理论结束:若当前数字与下级元素之后大于目标值,则后续所有的下级元素无需继续遍历
1、前置判断
数组元素前置判断,该判断在不合格的元素居多时收益才会较大,因此可以去除
// 数组元素前置判断
for (let i = 0; i < candidates.length; i++) {
const item = candidates[i];
if (item < target) {
} else if (item === target) {
results.push(candidates.splice(i--, 1));
} else {
candidates.splice(i--, 1);
}
}
2、代码优雅程度优化 减少代码量
const comb = (start, sum, arr) => {
/* code */
comb(index, nextSum, arr.concat(combItem));
/* code */
};
comb(0, 0, []);
1、函数传入 candidates 与在上层作用域查找 candidates 的优缺点 传入 candidates 读取会更快? 传入 candidates 内存消耗会变多?