一道backtracking的启蒙作用的题,我还画了过程图在ppt,非常经典。。。
核心单元是一个List item (之前的题,可能是一个string,或者一个括号的string。。。上一道题,求sum,那么核心单元就是加和)
public class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
//if(nums==null || nums.length==0) return result;
//Arrays.sort(nums); // remember the function name!! Arrays.sort()!! Not Array.sort()
// 以上这一步其实是本题中不需要的,因为AC了。。看具体的题意来设计就好。。。
List<Integer> elemList = new ArrayList<Integer>();
backtracking(result, elemList, nums, 0);
return result;
}
public void backtracking(List<List<Integer>> result, List<Integer> elemList, int[] nums, int index){
result.add(new ArrayList<Integer>(elemList));
for(int i=index; i<nums.length; i++){
elemList.add(nums[i]); // 一开始犯错:把 nums[i] 写成了 nums[index]!!! 大错特错!!! 这就要求你对这个index的意思了解得特别清楚!!!什么是index,index有两层意思:1,当前需要添加到元素的index,2,一个结束条件!!这个非常重要!! 你应该记得,在dfs中,会设定一个base case,那就是当index==nums.length-1时,就要return了。
// 但是在这里,并没有return,所以是跑完了整个程序就自动结束了,因为是void类型!那么就是执行完 for loop里面的每一个iteration就跑完,结束了!!
backtracking(result, elemList, nums, i+1); // !!小心犯错,这里必须是i+1, 不是index+1, index是在这个iteration内,是静止的,只是作为起点!!动态变化的是 i
// 进行了add 当面元素之后,就是变化出现!!!就是生成一个增长的elemList,于是就是要继续对这个elemList进行两个操作,1,copy paste,加入result,2,在接下来的index+1 处抓一个元素出来,进行添加。。这两个步骤都包含在backtracking()这个自身调用的函数中,所以index的意义就在于此!! 通过分析+假象似的解说,我有发现了一个非常容易懂的visualize the process的过程。。。这个过程是我今天最大的收获,也是我过去几个星期关于backtracking这个方法的一个跨越性的理解!!
elemList.remove(elemList.size()-1);
}
}
}