LeetCode 78 子集 | 解题思路分享

news2025/1/12 20:58:22

原题链接:78. 子集 - 力扣(LeetCode)

题目难度:中等

题目描述

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

解题思路

PS:这里先写的是思考过程中的错误解法,没有兴趣的同学可以直接跳过哈哈哈🤣

这题还是有点意思的,我第一眼看上去就觉得是用递归去做,递归的内部循环每一个元素,循环中去移出元素,之后递归,再把刚移出的元素添加进去。

想法很简单,思路很明确,于是直接开始写代码,核心代码如下:

List<List<Integer>> ans = new ArrayList<>();

void trade(List<Integer> list) {
    ans.add(new ArrayList<>(list));
    if (list.size() == 0) {
        return;
    }
    ArrayList<Integer> temp = new ArrayList<>(list);
    for (Integer num : temp) {
        list.remove(num);
        trade(list);
        list.add(num);
    }
}

结果执行用例就出现了问题,发现存在大量重复元素,因为这个方法对前面递归的状态没有关系,即使在循环中移出过的元素,再下一层循环的下一层递归中仍有可能被继续移出。

比如集合【1,2,3】:

  1. 最外层递归的第一次循环:移出1 递归-> 移出2 递归-> 移出3,产生的列表有 [2,3],[3]
  2. 最外层递归的第二次循环:移出2 递归-> 移出1 递归-> 移出3,产生的列表有 [1,3],[3]

如此便产生了两个[3]。


解法一:递归状态

仍然还是递归,但我们可以把思路转换成,每一个数字都只有两种状态,被选择和不被选择,这样一来,便可以找到所有子集,且不重复。

  1. 构建一个Stack,用于存储当前已经选择了的元素。(因为用栈方便我删除刚刚存储的元素,恢复状态)

  2. 循环每一个元素,对于每一个元素,有如下两种状态

    1. 选择该元素,那么将元素值入栈,再调用函数递归

    2. 不选择该元素,由于刚刚已经入栈了,所以我们需要出栈一次,然后再继续递归。

      这里出栈的同时也保证了栈在本层递归中的状态被还原,不会影响上一层递归的操作。

  3. 当所有元素都被处理过一遍了,不管是选择了还是没选择,那都会得出一个唯一的栈序列,此时将该栈深拷贝一份,并且作为列表存入答案中。

核心代码如下:

public List<List<Integer>> subsets(int[] nums) {
    this.nums = nums;
    List<Integer> list = Arrays.stream(nums).boxed().collect(Collectors.toList());
    trade(list);
    return ans;
}

int[] nums;

Stack<Integer> stack = new Stack<>();

List<List<Integer>> ans = new ArrayList<>();

void doit(int i) {
    if (i == nums.length) {
        // 当所有数字都选择完后,保存当前状态
        ans.add(new ArrayList<>(stack));
        return;
    }
    // 选择当前元素
    stack.push(nums[i]);
    doit(i + 1);
    // 不选择当前元素
    stack.pop();
    doit(i + 1);
}

解法二:二进制类比

对于上一种解法,我们知道每个元素都只有两种状态,如果我们将这两种状态用0,1表示,那题目所需要求出的答案,就像可以类比成这样的序列:

000、001、010、100、011、110、101、111

把他们排好看点:

000、001、010、011、100、101、110、111

不容易发现😅,这其实正是0、1、2、3、4、5、6、7的二进制值。

这样一来,我们只需要把一个数字不断递增,再递增的过程中使用其二进制求出每一个对应的元素序列,就可以得到答案,简直绝了😥。

而我们递增的次数,就是2的序列长度次方。

核心代码如下:

public List<List<Integer>> subsets(int[] nums) {
    int n = (int) Math.pow(2, nums.length);
    List<List<Integer>> ans = new ArrayList<>();
    for (int i = 0; i < n; i++) {
        ArrayList<Integer> list = new ArrayList<>();
        // t 用来求二进制的每一位是否为1
        // j 用来取序列的下标
        for (int t = i, j = 0; t != 0; t >>= 1, j++) {
            if ((t & 1) == 1) {
                list.add(nums[j]);
            }
        }
        ans.add(list);
    }
    return ans;
}

通过截图:

image-20230111162156071

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156601.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

忆享聚焦|5G投资、网络安全市场、云计算、Web3技术……近期热点资讯一览

“忆享聚焦”栏目第11期来啦&#xff01;本栏目汇集近期互联网最新资讯&#xff0c;聚焦前沿科技&#xff0c;关注行业发展动态&#xff0c;筛选高质量讯息&#xff0c;拓宽用户视野&#xff0c;让您以最低的时间成本获取最有价值的行业资讯。目录行业资讯1. SA&#xff1a;全球…

ubuntu虚拟机VmWare与主机共享文件夹

一、说明&#xff1a; 宿主操作系统&#xff1a;Windows 11 64位。 客户操作系统&#xff1a;Ubuntu 18.04.1 64位。 虚拟机软件&#xff1a;VMware Workstation 17 pro 二、步骤&#xff1a; 1、参考教程链接1&#xff0c;在主机设置共享文件夹。 注意&#xff1a;教程链接…

聚焦技术,2022巨杉荣获国内外多家权威机构认可

作为分布式数据库的领先企业 巨杉成立十年来&#xff0c;一直聚焦分布式技术的自研与深耕 在分布式数据库领域已取得丰硕的成果 回望2022&#xff0c;巨杉除在客户案例及产品方面屡获殊荣外 也凭借过硬的技术实力及规模化的行业应用 得到多家国内外权威机构的认可 国际权威…

TensorRT学习笔记--基本概念和推理流程

目录 前言 1--Tensor RT基本概念 2--推理流程 3--实例代码 前言 以下 Tensor RT 的基本概念和推理流程均为博主自我的理解&#xff0c;可能部分内存会存在错误或偏差&#xff0c;仅供参考&#xff01; 1--Tensor RT基本概念 ① Logger&#xff1a;日志记录器&#xff0c;…

ssm:spring定时任务Task和CronExpression表达式

开发一个定时任务&#xff1a;每天晚上23点执行数据归集任务 首先Spring配置文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.or…

Java中的常用的代理模式

本文介绍在Java种常用的3种动态代理。 代理模式是23种模式中的一种&#xff0c;属于结构型设计模式。这种模式的作用就是要创建一个中间对象&#xff08;相当于中介或者代理对象&#xff09;&#xff0c;通过操作中间对象来间接调用目的对象的方法&#xff0c;字段等&#xff0…

Everything搜索知识总结

1.只知道那个文件以 .txt结尾 .*\.txt$ ($表示以什么结尾) 2.搜索某个路径下的文件 D:\ configure.bat (搜索D盘下的该文件,注意要用这种类型的"\",和被搜索的文件之间有空格;要先打出路径,再打出搜索文件.) 3.搜索指定路径下的多个文件 路径\ 文件1 | …

Halcon亚像素边缘缺陷检测案例

一、下面的案例是总结的Halcon边缘缺陷检测的一种情况。本案例是利用阈值分割获取金属区域&#xff0c;并利用boundary和edges_sub_pix获取到亚像素边缘。然后综合利用fit_rectangle2_contour_xld拟合出金属对应的放射矩形&#xff0c;最后利用dist_rectangle2_contour_points_…

【小白课程】openKylin用户手册原理解析,一招教你学会自定义!

openKylin用户手册是详细描述openKylin操作系统的功能和用户界面&#xff0c;让用户了解如何使用该软件的说明书。通过阅读openKylin用户手册&#xff0c;能够更快更好的上手和使用openKylin操作系统。今天就带大家简单了解下openKylin用户手册的实现原理以及如何自定义用户手册…

用EditPlus编译Fortran

一、EditPlus配置 语法点亮 安装好EditPlus后&#xff0c;点击Tool->Prefenrences&#xff0c;在File->Setting&syntex下&#xff0c;点击Add按钮&#xff0c;填Frotran。 到EditPlus官网上 EditPlus - User Files (other files) 下载Fortran语法文件 ​ 二、配置…

设计模式学习(四):Strategy策略模式

一、什么是Strategy模式 Strategy的意思是“策略”&#xff0c;指的是与敌军对垒时行军作战的方法。在编程中&#xff0c;我们可以将它理解为“算法”。无论什么程序&#xff0c;其目的都是解决问题。而为了解决问题&#xff0c;我们又需要编写特定的算法。使用Strategy模式可以…

Redis- 主从复制原理

1、概述 Master节点在平时提供服务&#xff0c;另外一个或多个Slave节点在平时不提供服务&#xff08;或只提供数据读取服务&#xff09;。当Master节点由于某些原因停止服务后&#xff0c;再人工/自动完成Slave节点到Master节点的切换工作&#xff0c;以便整个Redis集群继续向…

Spring依赖注入源码分析

1. 前言 Spring的核心之一就是依赖注入&#xff0c;Spring提供了Autowired注解来给bean注入依赖。除了注入最基本的bean之外&#xff0c;Spring还做了一些扩展&#xff0c;例如你可以注入Optional&#xff0c;以此来判断依赖的bean是否存在&#xff1b;你还可以注入Map来获得所…

Leetcode:617. 合并二叉树(C++)

目录 问题描述&#xff1a; 实现代码与解析&#xff1a; 递归&#xff1a; 原理思路&#xff1a; 迭代&#xff1a; 原理思路&#xff1a; 问题描述&#xff1a; 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&am…

leetcode 399. 除法求值-java题解

题目所属分类 flod最短路算法 原题链接 给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件&#xff0c;其中 equations[i] [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。 另有一些以数组 queri…

编译metabase

Linux Centos7 配置Metabase编译打包环境 安装Oracle JDK1.8&#xff08;如果已经安装&#xff0c;则可以省略此步骤&#xff0c;必须是Oracle JDK&#xff09; 在线下载Oracle JDK 1.8 将下载好的tar包放入linux目录下 2、解压tar进行安装 tar -zxvf jdk-8u212-linux-x64.t…

SSL/TLS协议信息泄露漏洞(CVE-2016-2183)

最近服务器扫描出SSL/TLS协议信息泄露漏洞(CVE-2016-2183) TLS是安全传输层协议&#xff0c;用于在两个通信应用程序之间提供保密性和数据完整性。 TLS, SSH, IPSec协商及其他产品中使用的DES及Triple DES密码存在大约四十亿块的生日界&#xff0c;这可使远程攻击者通过Sweet…

总结几个常用的Git命令的使用方法

目录 1、Git的使用越来越广泛 2、设置Git的用户名和密码并查看 3、建立自己的 Git 仓库 4、将自己的代码提交到远程 (origin) 仓库 5、同步远程仓库的更新到本地仓库 6、分支管理 7、获取远程仓库的内容 1、Git的使用越来越广泛 现在很多的公司或者机构都在使用Git进行项目和代…

Elasticsearch基础1——搜索引擎发展史和工作流程、es\es-head\kibana的基础安装

文章目录一、搜索引擎1.1 搜索引擎的发展背景1.2 Lucene和Elasticsearch1.3 Solr和Elasticsearch对比1.4 数据搜索方式1.5 搜索引擎1.5.1 搜索引擎工作流程1.5.2 网络爬虫原理流程1.5.3 网页分析1.5.4 正排索引和倒排索引二、Elasticsearch基础安装1.2 概述简介2.2 安装2.2.1 W…

tensorflow算子注册以及op详解

在自定义的算子时&#xff0c;经常遇到一些函数和宏&#xff0c;这里介绍一下常见的函数和宏 REGISTER_OP 首先我们来思考REGISTER_OP的作用是什么&#xff1f;当我们定义一个tensorflow的算子&#xff0c;首先我们需要tensorflow知道这个算子&#xff0c;也就是说我们要把这…