回溯算法-leetcode78 子集(java)

子集

  • leetcode78 子集
    • 题目描述
  • 子集问题的解题思路
    • 代码框架
    • 子集解题代码
  • 动态规划专题

leetcode78 子集

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/subsets

题目描述

给你一个整数数组 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 中的所有元素 互不相同

子集问题的解题思路

子集问题是不考虑顺序的。
这题我们用回溯算法,首先介绍下回溯算法的解题套路
回溯算法的本质是暴力递归,遍历所有的可能性分支(决策分支)。

解决一个回溯问题,实际上就是遍历一个决策树的过程,在每一个回溯的节点上,都要注意三个问题:
1.已经做出的选择,
2.可以继续做出的选择
3.结束条件:也就是到了无法做出决策的条件

回到这题,我们先演示下,决策的过程,
1.什么都不选的空子集 s_0
回溯算法-leetcode78 子集(java)_第1张图片
和只选择一个元素的子集s_1

第二步,可以继续做出的选择
回溯算法-leetcode78 子集(java)_第2张图片
1下面可以继续做出的选择是2,3,
2下面的选择只有3,因为子集是没有顺序的,因此1不需要再选了
3下面没有可做出的选择了,
也就是结束条件,我们用一个变量去标记,3已经是来到了数组的末尾,没法继续做出选择了,

每次做出选择后,要撤销选择,因为是递归,要保证对递归过程不产生影响,

代码框架

result = []
def process(选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择

子集解题代码

class Solution {
    List<List<Integer>> res = new LinkedList<>();
    // 记录回溯算法的递归路径
    LinkedList<Integer> track = new LinkedList<>();

    // 主函数
    public List<List<Integer>> subsets(int[] nums) {
        backtrack(nums, 0);
        return res;
    }

    // 回溯算法核心函数,遍历子集问题的回溯树
    public void backtrack(int[] nums, int start) {

      res.add(new LinkedList<>(track));
      for(int i = start;i < nums.length;i++){
      		//做出的选择
          track.addLast(nums[i]);
          //走出选择后,去下一个位置去继续做选择
          backtrack(nums,i + 1);
          //撤销选择,上一次递归完成后,撤销选择,继续进行下一次递归
          track.removeLast();
      }
    }
}

动态规划专题

将数组分成两个数组,并最小化数组和的差II

将数组分成两个数组,并最小化数组和的差

leetcode337. 打家劫舍 III

leetcode213. 打家劫舍 II

leetcode198. 打家劫舍

动态规划–整数拆分问题

你可能感兴趣的:(java,数据结构,算法,算法,java,leetcode,数据结构,动态规划)