leetcode 78.子集
题解78.子集 (Subsets)1. 题目描述给定一个不含重复元素的整数数组nums返回该数组所有可能的子集幂集。要求解集不能包含重复的子集。你可以按任意顺序返回解集。示例输入nums [1,2,3]输出[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]2. 解题思路回溯算法 (Backtracking)本题是经典的组合问题适合使用回溯算法解决。回溯算法的核心思想是“做选择” - “递归探索” - “撤销选择”。我们可以把寻找子集的过程想象成遍历一棵决策树根节点空集[]。分支对于每个位置我们有两个选择选当前数字加入路径。不选当前数字通过循环跳过或回溯实现。叶子节点当没有更多数字可选时到达路径终点。核心逻辑拆解在代码中我们通过backtrack函数模拟这个过程记录结果每次进入backtrack函数当前的路径curr都是一个合法的子集直接加入结果集result。注意这里需要拷贝数组[...curr]因为curr是引用类型后续会被修改。遍历选择从start索引开始遍历nums。start参数的作用保证不重复选择之前的元素且避免生成重复子集如[1,2]和[2,1]视为同一个。做选择 (Push)将nums[i]加入当前路径curr。递归深入调用backtrack(i 1, curr)。传入i 1表示下一层只能从当前元素的后面开始选防止回头选造成重复。撤销选择 (Pop) —— 关键步骤递归返回后必须执行curr.pop()。目的将状态恢复到“做选择之前”以便在同一层级尝试下一个数字即换一条路走。原理这就是“回溯”的含义——退回到上一步重新选择。3. 代码实现 (JavaScript)/** * param {number[]} nums * return {number[][]} */varsubsetsfunction(nums){constresult[];/** * 回溯函数 * param {number} start - 当前遍历的起始索引 * param {number[]} curr - 当前路径正在构建的子集 */functionbacktrack(start,curr){// 1. 前序位置将当前路径加入结果集// 注意必须使用 [...curr] 进行浅拷贝否则 result 中存储的都是同一个引用result.push([...curr]);// 2. 遍历选择列表for(letistart;inums.length;i){// --- 做选择 ---curr.push(nums[i]);// --- 递归进入下一层 ---// i 1 确保不会重复使用当前元素也不会回头选前面的元素backtrack(i1,curr);// --- 撤销选择 (回溯) ---// 关键点移除最后一个元素回到上一层状态以便尝试下一个 icurr.pop();}}// 从索引 0 开始初始路径为空backtrack(0,[]);returnresult;};4. 复杂度分析假设数组长度为N NN。时间复杂度:O ( N ⋅ 2 N ) O(N \cdot 2^N)O(N⋅2N)一个长度为N NN的数组其子集总数为2 N 2^N2N个。构建每个子集拷贝数组平均需要O ( N ) O(N)O(N)的时间。总时间 子集数量× \times×构建成本 2 N × N 2^N \times N2N×N。空间复杂度:O ( N ) O(N)O(N)主要消耗在递归栈的深度。最坏情况下递归深度为N NN例如路径[1, 2, ..., N]。注如果不计算存储结果result所需的空间仅计算算法运行时的额外空间则为O ( N ) O(N)O(N)。如果算上结果集则是O ( N ⋅ 2 N ) O(N \cdot 2^N)O(N⋅2N)。5. 常见疑问解答 (QA)Q1: 为什么要用[...curr]而不是直接result.push(curr)A: JavaScript 中数组是引用类型。curr在整个递归过程中是同一个数组对象。如果不拷贝result里存的都是指向curr的指针。当递归结束curr最终会变成空数组[]那么result里所有的子集都会变成[]。使用[...curr]创建了一个新的副本锁定了当前的状态。Q2:curr.pop()到底是在什么时候执行的A: 它是在递归调用返回之后立即执行的。想象你走进一个房间递归做完事情出来后必须把门关上pop恢复原状才能去进下一个房间。如果你走了 3 步深push 了 3 次返回时就会依次执行 3 次 pop一步步退回到起点。Q3: 为什么循环要从start开始而不是从0开始A: 为了避免重复组合和顺序不同但内容相同的子集。如果从0开始会生成[1, 2]和[2, 1]这在子集问题中被视为重复。限制i start保证了我们只向后看不回头从而天然去重并保持有序。6. 总结这道题是回溯算法的模板题。掌握它的关键在于理解递归树的结构每一层代表做一个选择。状态重置push和pop必须成对出现像括号一样包裹递归调用。剪枝/去重通过start参数控制搜索范围。只要理解了“前进做选择后退撤选择”这一核心逻辑就能轻松解决类似的组合、排列、子集问题。

相关新闻

在华为arm64 kylin计算机上安装docker编译llama.cpp的步骤

在华为arm64 kylin计算机上安装docker编译llama.cpp的步骤

起因是试图将另一台arm64 kylin计算机上用gcc docker 容器编译的llama.cpp文件复制到这台机器上用,结果运行报错, 想用apt安装动态库也报错了,更新目录失败。 aaakylin-pc:~/bin$ ./llama-cli -v ./llama-cli: error while loading shared libraries: li…

2026/5/17 11:26:17 阅读更多 →
Kylin V10 SP1实战:从零部署NVIDIA Container Toolkit完整指南(附避坑清单)

Kylin V10 SP1实战:从零部署NVIDIA Container Toolkit完整指南(附避坑清单)

Kylin V10 SP1实战:从零部署NVIDIA Container Toolkit完整指南(附避坑清单) 在国产化替代浪潮中,麒麟操作系统(Kylin Linux Advanced Server V10)正成为越来越多企业和机构的首选。然而,当需要在…

2026/7/6 17:02:29 阅读更多 →
手把手教你优化RTC供电电路:从二极管选型到VBAT引脚配置全攻略

手把手教你优化RTC供电电路:从二极管选型到VBAT引脚配置全攻略

手把手教你优化RTC供电电路:从二极管选型到VBAT引脚配置全攻略 你是否曾遇到过这样的尴尬:精心设计的设备,在断电后其内部实时时钟(RTC)的电池续航时间远低于预期?或者,明明选用了高品质的纽扣电…

2026/5/17 11:26:17 阅读更多 →

最新新闻

中国一共有多少IP地址?(非常详细)

中国一共有多少IP地址?(非常详细)

为了照顾初学者,咱们先来科普一下 IP 地址的概念。IP 地址是 Internet Protocol Address 的缩写,译为“网际协议地址”。现阶段 IP 地址有两个版本,分别是 IPv4 和 IPv6。目前大部分软件仍在使用 IPv4 地址,但是 IPv6 地址也正在被…

2026/7/8 8:03:31 阅读更多 →
如何彻底解决网盘下载限速问题:9大平台直链解析工具完全指南

如何彻底解决网盘下载限速问题:9大平台直链解析工具完全指南

如何彻底解决网盘下载限速问题:9大平台直链解析工具完全指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 …

2026/7/8 7:59:29 阅读更多 →
9大主流网盘直链解析工具:告别限速困扰的高效下载解决方案

9大主流网盘直链解析工具:告别限速困扰的高效下载解决方案

9大主流网盘直链解析工具:告别限速困扰的高效下载解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / …

2026/7/8 7:57:29 阅读更多 →
D3KeyHelper:5分钟打造你的暗黑3专属鼠标宏,彻底告别手酸烦恼

D3KeyHelper:5分钟打造你的暗黑3专属鼠标宏,彻底告别手酸烦恼

D3KeyHelper:5分钟打造你的暗黑3专属鼠标宏,彻底告别手酸烦恼 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 还在为暗黑破坏…

2026/7/8 7:57:29 阅读更多 →
.NET 项目集成可观测性:从架构思考到落地实践

.NET 项目集成可观测性:从架构思考到落地实践

本文基于一个真实的.NET 9项目集成可观测性栈的经历,分享从"为什么做"到"怎么落地"的完整过程。一、为什么需要集成可观测性? 1.1 触发点:一个"慢"接口 项目中有一个业务接口,涉及多表关联、缓存查…

2026/7/8 7:51:28 阅读更多 →
终极AI换脸指南:如何用roop-unleashed实现电影级面部替换效果

终极AI换脸指南:如何用roop-unleashed实现电影级面部替换效果

终极AI换脸指南:如何用roop-unleashed实现电影级面部替换效果 【免费下载链接】roop-unleashed Evolved Fork of roop with Web Server and lots of additions 项目地址: https://gitcode.com/gh_mirrors/ro/roop-unleashed 在数字创意领域,AI换脸…

2026/7/8 7:49:27 阅读更多 →

日新闻

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: …

2026/7/8 0:00:48 阅读更多 →
MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N1 到批处理的全路径 一、从"功能正确"到"性能可接受"——MyBatis 批量操作的三段式进化 MyBatis 在日常增删改查场景中几乎是无感的——实体映射直观、SQL 控制灵活。但当数据量从千级上升到十万级、百万级,许…

2026/7/8 0:00:48 阅读更多 →
工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

1. 工业负载控制方案概述在工业自动化、电机驱动和照明控制等高需求场景中,可靠地控制电感和电阻负载是核心挑战之一。TPD2015FN作为东芝的8通道高端智能功率开关IC,配合PIC18F45K22微控制器,能够构建一套稳定、高效的负载控制系统。这套组合…

2026/7/8 0:02:48 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/7 14:24:45 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/7 15:59:06 阅读更多 →

月新闻