[LeetCode随记] No.78 子集

208 阅读1分钟
Medium -> leetcode-cn.com/problems/su…

给你一个整数数组 nums ,数组中的元素互不相同 。返回该数组所有可能的子集(幂集)。 解集不能包含重复的子集。你可以按任意顺序返回解集。 示例 1: 输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:
输入:nums = [0]
输出:[[],[0]]

提示:
    1 <= nums.length <= 10
    -10 <= nums[i] <= 10
    nums 中的所有元素[互不相同]
    
  • DFS 和回溯算法区别DFS 是一个劲的往某一个方向搜索,而回溯算法建立在 DFS 基础之上的,但不同的是在搜索过程中,达到结束条件后,恢复状态,回溯上一层,再次搜索。因此回溯算法与 DFS 的区别就是有无状态重置

  • 何时使用回溯算法当问题需要 回头,以此来查找出所有的解的时候,使用回溯算法。即满足结束条件或者发现不是正确路径的时候(走不通),要撤销选择,回退到上一个状态,继续尝试,直到找出所有解为止。

  • 怎么样写回溯算法(从上而下,*代表难点,根据题目而变化)

  1. 画出递归树,找到状态变量(回溯函数的参数)*
  2. 根据题意,确立结束条件
  3. 找准选择列表(与函数参数相关),与第一步紧密关联*
  4. 判断是否需要剪枝
  5. 作出选择,递归调用,进入下一层
  6. 撤销选择

原题解链接:leetcode-cn.com/problems/su…

回溯题型,该题中无剪枝需求;

定义全局变量path和用于返回的结果res,画出递归树。

d8e07f0c876d9175df9f679fcb92505d20a81f09b1cb559afc59a20044cc3e8c-子集问题递归树.png

class Solution {
    List<Integer> t = new ArrayList<Integer>();
    List<List<Integer>> ans = new ArrayList<List<Integer>>();

    public List<List<Integer>> subsets(int[] nums) {
        dfs(0, nums);
        return ans;
    }

    public void dfs(int cur, int[] nums) {
        ans.add(new ArrayList<Integer>(t));
        for(int i = cur; i < nums.length; i++){
            t.add(nums[i]);
            dfs(i+1, nums);
            t.remove(t.size()-1);
        }
    }