对于递归+回溯我觉得是需要多写多分析,递归三部曲:1.返回值和参数;2.终止条件;3.单层递归逻辑
1.通常情况下返回值都是void,参数的话根据实际需求设计,如果设置了全局变量那输入参数就可以少写几个,如果没有写全局变量输入参数就需要多写几个,一般就是存储结果的res,存放每条路径元素的path,然后如果要求和就要再加上sum,目标对比的target,基本就是这些。
2.终止条件,满足寻找的条件,单纯的组合就是元素个数满足需求,求和就是当前path中元素的和==target。总之就是当前的path中的元素满足条件了,就执行res.add的操作。
3.单层逻辑,这部分我觉得主要分成两个模块,一个是往path中添加元素,也就是深度上的遍历,或者说树枝的遍历,另外一部分是横向上的遍历,也就是往res中添加元素。后面的剪枝操作也是对树枝的修减或者对横向的深度的修减。
回溯过程:对于回溯过程我觉得也可以理解成纵向回退横向深入。如果把找组合的过程用树形图表示,回溯的部分就是纵向回退+横向深入,循环执行backtracking这一步,这是横向深入,而sum-=和removelast则是纵向回退。
这里统一规定used数组记录原candidates中各个元素使用情况。false没用,true用了。
然后根据题目需求,如果说收集到的path中也不能有重复,那同一树枝用过也要去掉,当然这个先去重我觉得也行;如果同样的组合不能重复出现就相当于同一树层要去重,也就是剪枝剪在横向深度上。跳过用过的元素就行。
40.组合总和2