最为典型的回溯法题目
回溯法其实都可以画树形图(决策树),用于解决排列组合问题,n皇后问题等等
注意这里的路径和选择列表
关注几点:
- 结束递归的条件
- 递归前的操作:加入路径
- 递归后的操作:撤销选择,等于是回到父节点
核心框架:
至于这道题的代码:
class Solution { List<List<Integer>> res=new ArrayList<>();//结果 public List<List<Integer>> permute(int[] nums) { List<Integer> track=new ArrayList<>();//路径,忘记加括号可还行,声明加了public是错的 backtracking(nums,track); return res; } public void backtracking(int[] nums,List<Integer> track) { //终止条件 if(track.size()==nums.length) { //res.add(track);这里注意 res.add(new ArrayList(track)); return; } //做出选择 for(int i=0;i<nums.length;i++) { if(track.contains(nums[i])) { continue;//相当于进入路径后,去除备选 } track.add(nums[i]);//加入路径 backtracking(nums,track); track.remove(track.size()-1); } } }
有几个点注意:
- 竟然还写错集合的new过程,手有点生了,乱加public可还行,
- 这里没有采取 加入路径-删除选择列表 这种搞法 而是在选择中加入判断,相当于进入路径后,去除备选
- 添加结果时要 new ArrayList(track),否则是弱引用
- 可以通过所谓交换等方式节省contains判断的时间