hot100-60子集

一、题目

给定一个整数数组nums,数组中的元素互不相同,返回该数组所有可能的子集。解集不能包含重复的子集,可以

按任意顺序返回。

二、思路

1、使用回溯算法,按顺序枚举每个元素"选"或"不选"的所有可能组合,通过控制起始下标 start 避免重复,每进入一次递归就将当前路径加入结果,从而生成所有子集。

三、代码

java 复制代码
class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        backtrack(nums,0,path,res);
        return res;
    }
    public void backtrack(int[] nums,int start,List<Integer> path,List<List<Integer>> res){
        res.add(new ArrayList<>(path));
        for(int i = start; i< nums.length;i++){
            path.add(nums[i]);
            backtrack(nums,i+1,path,res);
            path.remove(path.size()-1);
        }
    }
}

四、举例

【全排列 vs 子集】

1)子集无序**→ 用 start**

  • 原因:子集不关心顺序([1,2] = [2,1]),必须避免重复。

  • start 的作用:强制只往后选,不回头,保证每个组合只按一种顺序(如递增下标)生成,天然去重。

2)全排列有序 → 用 used

  • 原因:排列关心顺序([1,2] ≠ [2,1]),需要尝试所有未用过的元素,无论位置。

  • used 的作用:全局标记哪些元素已用,允许在任意位置选择任意未用元素,从而穷尽所有顺序。

3)全排列有终止条件(path.size() == n

  • 原因:全排列要求用完所有元素,只有当路径长度等于数组长度时,才是一个完整排列。

  • 所以只在此时才将结果加入答案。

4)子集"一进入就加元素"

  • 原因:子集可以是任意长度(包括空集),每一步的 path 都是一个合法子集。

  • 所以每次递归开始就记录当前状态,确保 [], [1], [1,2] 等都被收录。

相关推荐
dapeng28701 天前
分布式系统容错设计
开发语言·c++·算法
qq_417695051 天前
代码热修复技术
开发语言·c++·算法
Liu628881 天前
C++中的工厂模式高级应用
开发语言·c++·算法
AI科技星1 天前
全尺度角速度统一:基于 v ≡ c 的纯推导与验证
c语言·开发语言·人工智能·opencv·算法·机器学习·数据挖掘
条tiao条1 天前
KMP 算法详解:告别暴力匹配,让字符串匹配 “永不回头”
开发语言·算法
干啥啥不行,秃头第一名1 天前
C++20概念(Concepts)入门指南
开发语言·c++·算法
tobias.b1 天前
计算机基础知识-数据结构
java·数据结构·考研
zzh940771 天前
Gemini 3.1 Pro 硬核推理优化剖析:思维织锦、动态计算与国内实测
算法
2301_807367191 天前
C++中的解释器模式变体
开发语言·c++·算法
愣头不青1 天前
617.合并二叉树
java·算法