回溯法2,组合,条件,选择性
一.题源
https://www.lintcode.com/problem/subsets-ii/description
https://leetcode-cn.com/problems/subsets-ii/
不同于子集I,这次有一点小变化,就是在算法中加入了条件判断,即去除重复元素。将不满足的条件的结果剔除,不算入总结果集。
二.代码
public class Solution { public static void main(String[] args) { int[] arr = new int[]{1,2,2}; Arrays.sort(arr); ArrayUtils.displayArrayList(subsetsWithDup(arr)); } public static List<List<Integer>> subsetsWithDup(int[] nums) { List<List<Integer>> result = new ArrayList<>(); backTrace(result,new ArrayList<>(),nums,0); return result; } private static void backTrace(List<List<Integer>> result,List<Integer> list,int[] nums,int pos){ result.add(new ArrayList<>(list)); for (int i = pos; i < nums.length; i++) { //剔除重复的数字,除了第一个元素 if(i!=pos&&nums[i]==nums[i-1]){ continue; } list.add(nums[i]); backTrace(result,list,nums,i+1); list.remove(list.size()-1); } } }
输出:
[ [], [1], [1,2], [1,2,2], [2], [2,2] ]
三.图解分析
四. 总结
回溯法问题基本套路都一致
1.定义好总的结果集
2.定义好递归的出口和条件,比如长度超过最大值,下标超出原始数据长度等,当然有些情况可能不需要条件,那就让循环结束,自动退出就行。
3.计算局部结果集,把符合条件的结果加入局部结果集。
4.逐个从原始数据试探,试探一次,进入下一次递归。
5.将上次结果移除,进行一个数据的试探。
6.重复3-4,直到满足2退出,将局部结果保存至总结果集。