写在前面:本文的一些定义不一定是对的,我就是把我的思路写出来了。
递归一般是和树紧密相连的。回溯也可以认为是在树形结构中进行的。
回溯就是递归触底了然后向上返。同时在向上返的过程中要注意「恢复状态」。不能说返回到上一级了,状态还是当前层级的。
回溯问题一般和排列、组合问题关系比较密切。排列、组合需要枚举所有的可能性,枚举的过程就可以画出一棵树形图,然后在树里边选择符合题意的。因此解答回溯问题一般都是建议要先画出树形图。
画好树形图,就可以写代码了。
下面总结了几个技巧:
- 大概的框架:
这题是 39 号问题,这里只用来说明一般的代码框架。
public List<List<Integer>> combinationSum(int[] candidates, int target) { |
- 如果题目给的数据有重复元素,那么一般的做法是:
- 将给定的数组排序
- 在递归函数里用这句话处理重复元素:
if (i > idx && nums[i] == nums[i - 1]) continue;
。这样可以省略掉used
数组,如果想用used
数组的话,这样处理重复元素:if (used[i] || i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) continue;
。注意这两种方式的i
条件不一样,一个是i>idx
一个是i>0
。