ningendo

回溯法,子集,组合问题

一.题源

https://www.lintcode.com/problem/subsets/description

https://leetcode-cn.com/problems/subsets/

 

二.代码

public class Solution {
    public static void main(String[] args) {
        int[] arr = new int[]{0,1,2,3,4} ;
        ArrayUtils.displayArrayList(subsets(arr));
    }

    public static List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        backTrace(result,new ArrayList<Integer>(),nums,0);
        return result;
    }

    /**
     * 回溯法找子集
     * @param result 结果集
     * @param list  局部结果
     * @param nums  原始数据
     * @param pos   记录当前回溯的位置
     */
    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++) {
            //当前遍历到的数加入局部集
            list.add(nums[i]);
            //递归,从i+1开始找
            backTrace(result,list,nums,i+1);
            //移除上一次加入的数
            list.remove(list.size()-1);
        }
    }
}

  输出结果

[
    [],
    [0],
    [0,1],
    [0,1,2],
    [0,1,2,3],
    [0,1,2,3,4],
    [0,1,2,4],
    [0,1,3],
    [0,1,3,4],
    [0,1,4],
    [0,2],
    [0,2,3],
    [0,2,3,4],
    [0,2,4],
    [0,3],
    [0,3,4],
    [0,4],
    [1],
    [1,2],
    [1,2,3],
    [1,2,3,4],
    [1,2,4],
    [1,3],
    [1,3,4],
    [1,4],
    [2],
    [2,3],
    [2,3,4],
    [2,4],
    [3],
    [3,4],
    [4]
]

三.图解分析

 

 

 

 

一次循环:

 

  for(0:4)

 

    list.add(0)  (list :[0])----->第一层递归

 

                for(1:4)

 

            list.add(1)  (list [0,1])------->第二层递归

 

                          for(2:4)

 

                          list.add(2)  (list [0,1,2])  ------>第三层递归

 

                          list.remove(2)  (list[0,1])

 

                          list.add(3)  (list [0,1,3]) ----->第三层递归

 

            list.remove(1) (list [0])

 

            list.add(2)  (list [0,2])------->第二次递归

 

            .........

 

    list.remove(0) (list [])

 

    list.add(1)   (list [1])---->第一层递归

 

    .....

 

    

 

四.总结

好处:实现简单,代码简洁。

适用场景:数据集规模不大。

缺点:复杂度略高,复杂度为 O(n!) ,阶乘级别.

 

posted on 2020-10-14 16:50  Lunamonna  阅读(49)  评论(0编辑  收藏  举报

导航