leetcode_78:子集

这个题好意外啊,一顿分析猛如虎,一看战绩零杠五。其实我的思路是对的,只是在递归的时候没有想好参数,接下来说一下解题思路。

首先看到这个题目的话,应该能想到就是使用回溯法,也就是使用递归。在我们想到要用回溯法的时候,一般递归的参数里面都会有一个层数来告诉我们什么时候返回。这里也不例外,我们这里的层数指的就是数组的下标。

  1. 首先我们针对数组中的每个元素,把它构造成一个集合,并加到结果集中。
  2. 针对每个元素构成的集合,我们进行递归,以这个集合为母集合,将它传到下一层递归中。
  3. 下一层递归接受上一层传下来的母集合,然后加上当前下标的元素组成一个新集合,将这个新集合加入到结果集中。
  4. 以构造的新集合继续作为母集合,传到下一层递归中,直到层数为最后一层返回。

我们过一个图可以很形象的说一下,刚开始是一个空集合,然后依次把1,2,3加入到结果集中。当然再加入1的时候我们是要先递归,等它递归完我们才可以加入2,3。因为上面我们说到,递归的时候要记录层数,因此我们始终从前往后遍历,这样不会有重复。

假如我们将1加到结果集中了,然后将1作为母集合传到下一层,当前指针便会从2开始遍历,依次将2,3加入到母集合中,相似的是将3加入母集合之前集合[1,2]要继续递归完成后才会加入3。集合[1,2]加入到结果集后作为母集合传到下一层,下一层只会有一个3,因此加入完3以后就会返回)。图中带圈的序号就是加入到结果集中的顺序,可以自行体会一下。
在这里插入图片描述

下面是代码:

    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> temp = new ArrayList<>();
        result.add(temp);
        if (nums.length == 0)
            return result;
        backtrace(result, temp, 0, nums);
        return result;
    }

    private void backtrace(List<List<Integer>> result, List<Integer> temp, int curLevel, int[] nums) {
        if (curLevel == nums.length)
            return;
        for (int i = curLevel; i < nums.length; ++i) {
            List<Integer> curResult = new ArrayList<>(temp);
            curResult.add(nums[i]);
            result.add(curResult);
            backtrace(result, curResult, i+1, nums);
        }
    }
发布了96 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/reachwang/article/details/103517080