每日刷题记录(十四)

news2025/7/12 18:01:41

目录

  • 第一题:子集
    • 解题思路:
    • 代码实现:
  • 第二题:组合
    • 解题思路:
    • 代码实现:
  • 第三题:全排列
    • 解题思路:
    • 代码实现:
  • 第四题:全排列II
    • 解题思路:
    • 代码实现:
  • 第五题:括号生成
    • 解题思路:
    • 代码实现:

第一题:子集

给你一个整数数组 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,不包含记为0。如 [1, 2, 3] ,那么可以表示为

子集0/1序列
[]000
[1]001
[2]010
[3]100
[1, 2]011
[1, 3]101
[2, 3]110
[1, 2, 3]111

可以发现 0/1 序列二进制数的范围,刚好是十进制从 0 到 2 n − 1 2^n-1 2n1。那么,我们要做的,其实就只是把这个范围的数,按二进制,取每一位的数字,如果为1,表示原数组同样的索引位置,存放的元素存在子集中

  1. 0 0 0 开始遍历到 2 n − 1 2^n-1 2n1,即 0/1 序列的十进制数。
    其中 2 n 2^n 2n 使用二进制表示,即第 n 位为 1 ,其他位为 0 的数。可以使用 1<< n 来表示。
    如:二进制数 100000 共有 6 位,转换为十进制即 2 6 2^6 26,也即 1 左移 6 位。
  2. 每次遍历的 0/1 序列数,转换为二进制数后,取每一位数字。这里每一位,即 0 到 数组长度 的位数来取。取一个数 x ,二进制的第 j 位,可以把 x 右移 j 位,再和 1 进行按位与操作。如 50 ,二进制即 110010 ,第 0 位为最后一位,那么,要取第 1 位(即倒数第二位)的 1,可以先右移 1位,即 50 >> 1 ,得到 11001,然后和1按位与计算
  3. 第二步取得的每一位数字,如果是1,则去原数组该索引位置获取元素,保存子集中

代码实现:

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        int n = nums.length;
        List<List<Integer>> subset = new ArrayList<>();
        for(int i = 0;i < (1 << n);i++) {
            List<Integer> sub = new ArrayList<>();
            for(int j = 0;j < n;j++) {
                if(((i >> j) & 1) == 1) {
                    sub.add(nums[j]);
                }
            }
            subset.add(sub);
        }
        return subset;
    }
}

第二题:组合

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。

示例 1:

输入:n = 4, k = 2
输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]

示例 2:

输入:n = 1, k = 1
输出:[[1]]

提示:

  • 1 <= n <= 20
  • 1 <= k <= n

解题思路:

假如 n=4, k=2 ,即要在 [1, 2, 3, 4] 中求 2 个数的组合。
那么对每个组合来说, 1~4 范围内的每个数字都只有 包含 与 不包含 两种情况
则 dfs(1, 4) 可以分解为 dfs(1) 的组合与 dfs(2, 4) 组合:
(1) dfs(1) 为 1 的组合,即 [1] (包含 1 )、 [] (不包含 1 )。
(2)如果 dfs(1) 包含1,则 dfs(2, 4) 需要有 k-1=2-1=1 个元素来构建组合
(3)如果 dfs(1) 不包含1,则 dfs(2, 4) 需要有 k-0=2 个元素来构建组合

同样的, dfs(2, 4) = dfs(2) + dfs(3, 4) dfs(3, 4) = dfs(3) + dfs(4) 。

由以上分解的问题,最终可以采取如下步骤:

  1. 从1开始遍历到4,求取组合,保存在 List<List< Integer > > ,记为 ret 。
  2. 搜索到的组合保存在一个双端队列 Deque 中,记为 sub ,如果 sub 长度为 k ,则保存 sub 到 ret 。
  3. 每次遍历,先包含当前数字 cur ,即 sub 添加 cur ;同时进一步求解子问题 cur+1 到 n 的组合。这里最终的组合都包含 cur 。
  4. 求不包含当前数字 cur 的组合,所以还需要把 sub 中最后的元素 cur 删除;同时进一步求解子问题 cur+1到 n 的组合。这里最终组合都不包含 cur

代码实现:

class Solution {
      List<List<Integer>> ret = new ArrayList<>();
      Deque<Integer> sub = new ArrayDeque<>();
    public List<List<Integer>> combine(int n, int k) {
        dfs(n,k,1);
        return ret;
    }
    private void dfs(int n,int k,int cur) {
        if(sub.size() == k) {
            ret.add(new ArrayList(sub));
            return;
        }
        for(int i = cur;i <= n;i++) {
            sub.addLast(i);
            dfs(n,k,i+1);
            sub.removeLast();
        }
    } 
}

第三题:全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

提示:

  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

解题思路:

本题为一个回溯问题,实际上就是一个决策树的遍历过程。
在这里插入图片描述

  1. 路径:用双向队列sub接收已经做出的选择。
  2. 选择列表:当前可以做的选择。
  3. 结束条件:当sub的大小等于nums时,无法再做选择。

代码实现:

class Solution {
    List<List<Integer>> ret = new ArrayList<>();
    Deque<Integer> sub = new ArrayDeque<>();
    public List<List<Integer>> permute(int[] nums) {
        backTrack(nums);
        return ret;
    }
    private void backTrack(int[] nums) {
        if(sub.size() == nums.length) {
            ret.add(new ArrayList(sub));
            return;
        }
        for(int i = 0;i < nums.length;i++) {
            if(!sub.contains(nums[i])) {
            sub.addLast(nums[i]);
            backTrack(nums);
            sub.removeLast(); 
            }
        }
    }
}

第四题:全排列II

给定一个可包含重复数字的序列 nums ,按任意顺序返回所有不重复的全排列。

示例 1:

输入:nums = [1,1,2]
输出: [[1,1,2], [1,2,1], [2,1,1]]

示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

解题思路:

数组中包含了重复的数字,要求我们返回不重复的全排列,那么,我们可以将数组升序排序,这样如果相邻元素一样,在决策树就可以不选择同一层中,和上一个相同的元素

要判断同一层中的相邻元素,即数组相邻元素是否一样,需要再维护一个数组每个元素状态的列表:可以设置为boolean 数组,长度和原数组一样,当已选择,则同索引上的状态设为 true 。这样,我们在路径中,选择元素时,就可以不选择:

  1. 已选择该元素,不再选择
  2. 同一层相邻的上一个元素,和当前元素相等,且上一个元素未选择,则当前元素也不选择

代码实现:

class Solution {
    List<List<Integer>> ret = new ArrayList<>();
    Deque<Integer> sub = new ArrayDeque<>();
    boolean[] visits;
    public List<List<Integer>> permuteUnique(int[] nums) {
        visits = new boolean[nums.length];
        Arrays.sort(nums);
        backTrack(nums);
        return ret;
    }
    private void backTrack(int[] nums) {
        if(sub.size() == nums.length) {
            ret.add(new ArrayList(sub));
            return;
        }
        for(int i = 0;i < nums.length;i++) {
           if(visits[i] ||(i > 0 && nums[i] == nums[i-1] && !visits[i-1])) {
               continue;
           }
            sub.addLast(nums[i]);
            visits[i] = true;
            backTrack(nums);
            sub.removeLast(); 
            visits[i] = false;
        }
    }
}

第五题:括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3
输出:[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”]

示例 2:

输入:n = 1
输出:[“()”]

提示:

  • 1 <= n <= 8

解题思路:

本题属于全排列的一种变形,可以看出,输出的结果,为 n 个左括号,与 n 个右括号,在满足 左括号必须以正确的顺序闭合条件下的全排列。
本题使用搜索回溯算法+剪枝来实现

  • 当前左右括号都有大于 0 个可以使用的时候,才产生分支;
  • 产生左分支的时候,只看当前是否还有左括号可以使用;
  • 产生右分支的时候,需要已选择的左括号数量大于已选择的右括号数量;
  • 递归结束条件:在左边和右边剩余的括号数都等于 0的时候

代码实现:

class Solution {
    List<String> ret = new ArrayList<>();
    StringBuilder path = new StringBuilder();
    public List<String> generateParenthesis(int n) {
        backtrack(n,0,0);
        return ret;
    }
    private void backtrack(int n,int left,int right) {
        if(path.length() == n*2) {
            ret.add(path.toString());
            return;
        }   
        if(left < n) {
            path.append('(');
            backtrack(n,left+1,right);
            path.deleteCharAt(path.length()-1);
        }
        if(right < left) {
            path.append(')');
            backtrack(n,left,right+1);
            path.deleteCharAt(path.length()-1);
        }
    }
}

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

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

相关文章

2023年4月传统行业产品经理需要考NPDP吗?含金量高吗?

产品经理国际资格认证NPDP是新产品开发方面的认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年&#xff0c;是…

Linux内存管理(七):fixmap详解

源码基于:Linux 5.4 约定: 芯片架构:ARM64 CONFIG_ARM64_VA_BITS:39 CONFIG_ARM64_PAGE_SHIFT:12 0. 前言 内核启动首先会进入汇编阶段,mmu已经启动 (也就是说,当前SOC只能使用虚拟地址访问RAM),paging_init还没有完成调用,在内核启动过程需要访问某些特定的内核模…

SQL综合查询上

目录1、查询输出“高等数学”课程成绩前三名&#xff08;不考虑成绩有重复值的情况&#xff09;的学生的学号&#xff0c;姓名&#xff0c;课程名&#xff0c;系名&#xff0c;成绩。题目代码2、统计各门课程的重修人数&#xff08;包括grade为NULL&#xff09;&#xff0c;要求…

体验了一把ChatGPT4

不得不说ChatGPT对我的学习效率有极大的提升&#xff0c;它就像一位老师&#xff0c;不管有什么问题&#xff0c;都可以得到很好的答案。但是前段时间gpt3.5账号被封了&#xff0c;最近搞了个gpt4。市面上目前好像没啥可以白嫖的账号&#xff0c;基本都是免费使用几次&#xff…

C++11新特性有效总结

目录 语言可用性加强 (读现代C教程有感) nullptr constexpr if/switch 申明强化 &#xff08;C17开始&#xff09; 初始化参数列表 范围for迭代 两种类型推导方式 变长参数模板 SmartPointer Lambda 多线程 (并发与并行) 并发与并行的概念 C11中的并发并行 软件…

基于单片机的温室大棚环境监测系统设计

温室大棚对北方反季节蔬菜的种植具有重要意义。据了解全国各地温室大棚使用集中&#xff0c;但是大棚环境调控方式落后、管理落后、生产效率比较低。针对此问题本文提出了一种基于STM32单片机智能温室大棚控制系统方案&#xff0c;实现环境参数的自动检测&#xff0c;以达到智能…

C语言从入门到精通第2天(深度解析C语言数据类型及取值范围)

C语言基本数据类型及取值范围数据存储概述基本数据类型整型数的二进制表示浮点型数的二进制表示取值范围数据存储概述 C语言的变量有着不同的数据类型&#xff0c;每种数据类型的取值空间都是不同的&#xff0c;因此&#xff0c;不同数据类型的变量&#xff0c;其取值空间也不…

利用注解和反射解决代码冗余问题(改进版)

在优化代码的时候发现&#xff0c;传参存在着高度冗余&#xff0c;如果后面需要改参数&#xff0c;很不方便。 String pam1 "id" appKey "&sign" sign "&method" method "&access_token" token "&times…

光隔离器的工作原理及其应用

光隔离器也称为光隔离器或光耦合器&#xff0c;它是一种通过使用光将电信号或电压从一个电路传输到另一个电路的装置&#xff0c;同时它将两个电路彼此隔离。它可以通过隔离过压信号来防止高电压或快速变化的电压损坏组件。光隔离器可以承受高达10KV的输入至输出电压和高达10KV…

html+css+JavaScript+json+servlet的社区系统(手把手教学)

目录 课前导读&#xff1a; 一、系统前期准备 二、前端代码的编写 三、登陆页面简介 四、注册页面 五、社区列表页 六、社区详情页 七、社区发帖页 八、注销 九、访问链接 登陆页面http://175.178.20.77:8080/java106_blog_system/login.html 总结&#xff1a; 课前…

HTML5 <embed> 标签、HTML5 <figcaption> 标签

HTML5 <embed> 标签 实例 被嵌入的 flash 动画片&#xff1a; <embed src"helloworld.swf">尝试一下 浏览器支持 注意: 大多数现代浏览器已经弃用并取消了对浏览器插件的支持&#xff0c;所以如果您希望您的网站可以在普通用户的浏览器上运行&#xf…

【SpringCloud系列】开发环境下重写Loadbalancer实现自定义负载均衡

前言 spring-cloud-starter-netflix-ribbon已经不再更新了&#xff0c;最新版本是2.2.10.RELEASE&#xff0c;最后更新时间是2021年11月18日&#xff0c;详细信息可以看maven官方仓库&#xff1a;https://search.maven.org/artifact/org.springframework.cloud/spring-cloud-st…

【计算机图形学】裁剪算法(逐边裁剪法 Weiler-Atherton裁剪法)

一 实验目的 编写直线段、多边形裁剪算法熟悉逐边裁剪法、Weiler-Atherton裁剪法的使用 4&#xff1a;用逐边裁剪法实现多边形裁剪&#xff08;代码最上方功能区注明是否处理退化边&#xff09; 无退化实验结果如下图所示&#xff1a; 图形初始化&#xff1a;&#xff08;红色…

GaussDB工作级开发者认证—第五章GaussDB数据库操作与管理

一、数据库对象基本操作 查询数据库&#xff1a; postgres# \l --使用元命令查看数据库 postgres# select * from pg_database; --通过系统表查看数据库 表注意事项: 只有表的所有者有权限执行ALTER TABLE命令&#xff0c;系统管理员默认拥有此权限 不能修改分区表的tables…

creator-assetbundle分包

title: creator-assetbundle分包 categories: Cocos2dx tags: [creator, 分包, assetbundle] date: 2023-04-10 15:55:22 comments: false mathjax: true toc: true creator-assetbundle分包 前篇 Asset Bundle 介绍 - https://docs.cocos.com/creator/manual/zh/asset/bundle…

国家出手管人工智能AI了

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 全球都在封杀AI&#xff0c;国家也出手了&#xff0c;人工智能AI的强监管来了!这次反应速度算是很快了。国家出手&#xff0c;AI必须管。 国家网信办拟针对生成式人工智能服务出台管理办法&#…

【万象奥科】RZ/G2UL网关内存压力测试

测试目的 内存压力测试的目的是测试系统内存的稳定性和可靠性&#xff0c;以便确定系统是否能够在各种负载情况下正常运行。其主要目的有&#xff1a; 测试内存的正确性&#xff1a;通过模拟各种内存负载情况&#xff0c;例如写入随机数据、重复写入相同数据、使用指定的模式…

原型模式解读

目录 模式引进问题 原型模式 原型模式原理结构图-uml 类图 原型模式解决克隆羊问题的应用实例 深拷贝和浅拷贝 浅拷贝的介绍 深拷贝基本介绍 重写 clone 方法来实现深拷贝 通过对象的序列化实现实现深拷贝&#xff08;推荐&#xff09; 原型模式的注意事项和细节 模式…

阿里云linux云服务器 安装指定版本node.js

我们在实例管理中找到自己的服务器 然后点击右侧的 远程连接 接着点击理解登录 进入命令窗口 我们在这上面输入 curl -h阿里云的服务器都还是最好会有 curl的 然后 我们输入 sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash下把nv…

带头部表头和侧边表头样式的布局

原型设计的页面中的表格除了头部还有左侧侧边是表头的一个表格&#xff0c;查阅组件文档&#xff0c;发现表格table没有两个表头的布局。 思路&#xff1a; 1、使用div自己布局 2、使用表格table&#xff0c;修改其第一列样式背景&#xff0c;展示除了的样子看着像是有多个表头…