剑指Offer题目笔记24(集合的组合、排序)

news2024/11/24 1:22:44

面试题79:

面试题79

问题:

​ 输入一个不含重复数字的数据集合,找出它的所有子集。

解决方案:

​ 使用回溯法。子集就是从一个集合中选出若干元素。如果集合中包含n个元素,那么生成子集可以分为n步,每一步从集合中取出一个数字,此时面临两个选择,将该数字添加到子集中或不将该数字添加到子集中。生成一个子集可以分为若干步,并且每一步都面临若干选择。

源代码:
class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        helper(nums,0,new LinkedList<>(),result);
        return result;
    }
	
    private void helper(int[] nums,int index,LinkedList<Integer> list,List<List<Integer>> result){
        //扫描完数组后,将链表List<Integer>添加到链表List<List<Integer>>
        if(index == nums.length){
            result.add(new LinkedList<>(list));
        }else{
            //情况一:不添加该数字
            helper(nums,index + 1,list,result);
			
            //情况二:添加该数字
            list.add(nums[index]);
            helper(nums,index + 1,list,result);
            //删除链表中最后一个元素
            list.removeLast();
        }
    }
}

面试题80:

面试题80

问题:

​ 输入n和k,输出从1到n中选取k个数字组成的所有组合。

解决方案:

​ 使用回溯法。从1到n的集合中选出若干元素。如果组合只能有k个元素,那么生成组合可以分为k步,每一步从集合中取出一个数字,此时面临两个选择,将该数字添加到组合中或不将该数字添加到组合中。生成一个组合可以分为若干步,并且每一步都面临若干选择。

源代码:
class Solution {
    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> result = new LinkedList<>();
        dfs(n,1,k,new LinkedList<>(),result);
        return result;
    }
	//num用于标记当前数字
    private void dfs(int n,int num,int k,LinkedList<Integer> list,List<List<Integer>> result){
        //扫描完数组后,将链表List<Integer>添加到链表List<List<Integer>>
        if(list.size() == k){
            result.add(new LinkedList<>(list));
        }else if(num <= n){
            //情况一:不添加该数字
            dfs(n,num+1,k,list,result);
			//情况二:添加该数字
            list.add(num);
            dfs(n,num+1,k,list,result);
            //删除链表中最后一个元素
            list.removeLast();
        }
    }
}

面试题81:

面试题81

问题:

​ 给定一个没有重复数字的正整数集合,找出所有元素之和等于某个给定值的所有组合。同一个数字可以在组合中出现任意次。

解决方案:

​ 使用回溯法。将问题分为若干步来解决,每一步的面临若干选择。每一步从集合中取出下标为i的数字,此时面临两个选择,一个选择是跳过该数字,不将该数字添加到组合中,另一个选择就是将数字添加到组合中,由于一个数字可以在组合中重复出现,所以下一步仍然处理下标为i的数字,

源代码:
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> result = new LinkedList<>();
        dfs(candidates,target,0,new LinkedList<>(),result);
        return result;
    }
	
    private void dfs(int[] candidates,int target,int i,LinkedList<Integer> list,List<List<Integer>> result){
        if(target == 0){
            result.add(new LinkedList<>(list));
        }else if(target > 0 && i < candidates.length){
			//情况一:跳过该数字
            dfs(candidates,target,i+1,list,result);
			//情况二:添加该数字
            list.add(candidates[i]);
            dfs(candidates,target-candidates[i],i,list,result);
            list.removeLast();
        }
    }
}

面试题82:

面试题82

问题:

​ 给定一个可能包含重复数字的整数集合,请找出所有元素之和等于某个给定值的所有组合。

解决方案:

​ 使用回溯法。该题与前几题类似,但是组合可以有重复数字,但是组合不能相同,避免重复的组合的方法是当在某一步决定跳过某个值为m的数字时,跳过所有值为m的数字。为了方便跳过后面所有值相同的数字,先将集合中的所有数字排序,再进行跳跃。

源代码:
class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        //排序数组
        Arrays.sort(candidates);

        List<List<Integer>> result = new LinkedList<>();
        dfs(candidates,target,0,new LinkedList<>(),result);
        return result;
    }

    private void dfs(int[] candidates,int target,int i,LinkedList<Integer> list,List<List<Integer>> result){
        if(target == 0){
            result.add(new LinkedList<>(list));
        }else if(target > 0 && i < candidates.length){
            dfs(candidates,target,getNext(candidates,i),list,result);

            list.addLast(candidates[i]);
            dfs(candidates,target-candidates[i],i+1,list,result);
            list.removeLast();
        }
    }
	//跳过数组中值等于num的下标
    private int getNext(int[] candidates,int num){
        int next = num;
        while(next < candidates.length && candidates[num] == candidates[next]){
            next++;
        }

        return next;
    }
}

面试题83:

面试题83

问题:

​ 给定一个没有重复数字的集合,找出它的所有全排序。

解决方案;

​ 使用回溯法。如果输入的集合中有n个元素,那么生成一个全排列需要n步。当生成排列的第1个数字时会面临n个选项,即n个数字都有可能成为排列的第1个数字。生成排列的第1个数字之后接下来生成第2个数字,此时面临n-1个选项,即剩下的n-1个数字都有可能成为第2个数字。然后以此类推,直到生成最后一个数字,此时只剩下1个数字,也就只有1个选项。

源代码:
class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> result = new LinkedList<>();
        dfs(nums,0,result);
        return result;
    }

    private void dfs(int[] nums,int i,List<List<Integer>> result){
        //如果i等于nums.length,说明数组nums已经按顺序排序完成。
        if(i == nums.length){
            LinkedList<Integer> list = new LinkedList<>();
            for(int num:nums){
                list.add(num);
            }
            result.add(new LinkedList<>(list));
        }else{
            //排序每一个数,如数组中的所有元素都可以成为下标0的位置,包括它自己
            for(int j = i;j < nums.length;j++){
               
                swap(nums,i,j);
                dfs(nums,i+1,result);
                swap(nums,i,j);
            }
        }
    }
 	//交换两数字在数组的位置
    private void swap(int[] nums,int i,int j){
        if(i != j){
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
    }
}

面试题84:

面试题84

问题:

​ 给定一个包含重复数字的集合,找出它的所有全排列。

解决方案:

​ 使用回溯法。与上一题类似,但是添加了包含重复数字的条件,在上一题的基础上使用Set集合排序重复数字。

源代码:
class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> result = new LinkedList<>();
        dfs(nums,0,result);
        return result;
    }

    private void dfs(int[] nums,int i,List<List<Integer>> result){
        //如果i等于nums.length,说明数组nums已经按顺序排序完成。
        if(i == nums.length){
            LinkedList<Integer> list = new LinkedList<>();
            for(int num:nums){
                list.add(num);
            }
            result.add(new LinkedList<>(list));
        }else{
            //使用Set集合排除重复数字
            Set<Integer> set = new HashSet<>();
            for(int j = i;j < nums.length;j++){
                if(!set.contains(nums[j])){
                    set.add(nums[j]);

                    swap(nums,i,j);
                    dfs(nums,i+1,result);
                    swap(nums,i,j);
                }
            }
        }
    }

    private void swap(int[] nums,int i,int j){
        if(i != j){
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
    }
}

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

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

相关文章

苹果安卓双端短视频直播系统源码,带后台-支持二开和采集

搭建教程 1.PHP5.6-7.2 mysql 5.6 redis5.0 nginx1.15 2.宝塔就完全满足了 我刚开了台服务器&#xff0c;建议用阿里云的 我这个是腾讯云 先让服务器 自己装着 时间比较长 3.搭建前需要准备的东西 腾讯云直播、七牛存储、百度语音、腾讯地图等好多东西 七牛存储…

Adaboost集成学习 | Matlab实现基于GRU-Adaboost门控循环单元结合Adaboost集成学习时间序列预测(股票价格预测)

目录 效果一览基本介绍模型设计程序设计参考资料效果一览 基本介绍 Adaboost集成学习 | Matlab实现基于GRU-Adaboost门控循环单元结合Adaboost集成学习时间序列预测(股票价格预测) 模型设计 股票价格预测是一个具有挑战性的时间序列预测问题,可以使用深度学习模型如门控循环…

LeetCode-142. 环形链表 II【哈希表 链表 双指针】

LeetCode-142. 环形链表 II【哈希表 链表 双指针】 题目描述&#xff1a;解题思路一&#xff1a;快慢指针 判断是否有环见解题思路二&#xff1a;set()解题思路三&#xff1a;0 题目描述&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如…

Qt5.15以上版本在线安装步骤,可选择更多早期版本

以ubuntu系统为例&#xff1a; 1、先去下载在线安装程序&#xff1a; https://download.qt.io/official_releases/online_installers/ 选择合适的版本&#xff0c;这里是在x64机器的ubuntu虚拟机里安装QT&#xff0c;所以选择如下版本&#xff1a; 或者直接在终端执行如下命令…

VScode-配置文件

导入配置文件 ShiftCtrlp 输入&#xff1a; import 选择文件 点击确认 导出配置文件 设置选择导出 确认导出 保存为本地文件 保存文件

视频素材库哪个好?推荐8个网站助你精彩创作

大家好&#xff01;在视频创作的世界里&#xff0c;一个好的素材库就像是你在寻宝&#xff0c;能让你的作品焕然一新。那么&#xff0c;视频素材库哪个好呢&#xff1f;今天&#xff0c;我就来给大家分享8个超棒的视频素材网站&#xff0c;让你不再为了视频素材库哪个好&#x…

Boost之Log: (3)、简单封装

设计目标: 1、每个Logging source对应一个目录&#xff0c;可以设置日志文件数&#xff0c;日志大小&#xff0c;目录名&#xff0c;文件名等 2、所有logging source日志目录都在一个根目录下。 3、可以动态创建和删除logging source 4、打印出日期时间和日志严重等级 示例代码…

不同设备使用同一个Git账号

想要在公司和家里的电脑上用同一个git账号来pull, push代码 1. 查看原设备的用户名和邮箱 第1种方法&#xff0c; 依次输入 git config user.name git config user.email第2种方法&#xff0c; 输入 cat ~/.gitconfig2. 配置新设备的用户名和邮箱 用户名和邮箱与原设备保持…

(十一)RabbitMQ及SpringAMQP

1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;…

自动驾驶的世界模型:综述

自动驾驶的世界模型&#xff1a;综述 附赠自动驾驶学习资料和量产经验&#xff1a;链接 24年3月澳门大学和夏威夷大学的论文“World Models for Autonomous Driving: An Initial Survey”。 在快速发展的自动驾驶领域&#xff0c;准确预测未来事件并评估其影响的能力对安全性…

桶排序---

1、算法概念 桶排序&#xff1a;一种非比较的排序算法。桶排序采用了一些分类和分治的思想&#xff0c;把元素的值域分成若干段&#xff0c;每一段对应一个桶。在排序的时候&#xff0c;首先把每一个元素放到其对应的桶中&#xff0c;再对每一个桶中的元素分别排序&#xff0c…

跨境运营必看:TikTok账号防封指南

多人在使用TikTok的过程中都会遇到一些问题&#xff0c;比如为什么TikTok没有浏览量&#xff1f;事实上&#xff0c;这很可能是因为你的账号已被禁止。但为什么它会被封呢&#xff1f;你怎样才能解决它&#xff1f; 一、TikTok账号为什么被封&#xff1f; 1、什么是 TikTok 影…

友思特方案 | 构建缤纷:可调谐光源的荧光成像的应用

导读 生物荧光分析常常伴随使用多种荧光染料的需求。结合多通道光源技术与高性能成像设备&#xff0c;友思特可调谐光源荧光检测成像方案&#xff0c;以其灵活的系统组成&#xff0c;满足了丰富的荧光检测应用需求。 生物荧光分析技术 激发荧光成像技术是研究生物学过程的一种…

越南工厂连接中国总部服务器解决方案---案例分享

随着全球化的不断深入&#xff0c;许多中国企业走出国门&#xff0c;在世界各地设立分支机构和生产基地。然而&#xff0c;随之而来的是跨国网络通信的挑战。近期&#xff0c;客户越南的工厂与中国总部之间的网络连接出现了一些问题&#xff0c;这直接影响了企业的日常运营效率…

身份证实名认证接口会返回什么?javascript身份核验接口示例

身份证实名认证接口是通过核验身份证号、姓名、证件头像等一系列的要素信息进行用户身份验证&#xff0c;那么&#xff0c;身份证实名认证接口一般在核验完成后会返回什么参数信息呢&#xff1f;下面翔云API小编为大家答疑解惑&#xff01; 一般情况下&#xff0c;身份核验只会…

索引下推(Index Condition Pushdown,简称 ICP)

Mysql可以分为Server层和存储引擎层 所以&#xff0c;最终进行I/O的是存储引擎对文件系统进行I/O操作 索引下推&#xff08;Index Condition Pushdown&#xff0c;简称 ICP&#xff09; 对应InnoDB&#xff0c;索引下推适用于非聚簇索引&#xff08;二级索引&#xff09;。 …

深度学习理论基础(六)注意力机制

目录 深度学习中的注意力机制&#xff08;Attention Mechanism&#xff09;是一种模仿人类视觉和认知系统的方法&#xff0c;它允许神经网络在处理输入数据时集中注意力于相关的部分。通过引入注意力机制&#xff0c;神经网络能够自动地学习并选择性地关注输入中的重要信息&…

Oracle常用sql命令(新手)

1、备份单张表 创建复制表结构 create table employeesbak as select * from cims.employees 如果只复制表结构&#xff0c;只需要在结尾加上 where 10 插入数据 insert into employeesbak select * from cims.employees 删除一条数据 delete from…

探索数字社交的边界:揭示Facebook如何塑造未来社交媒体的发展趋势

在当今数字化时代&#xff0c;社交媒体已经成为人们生活中不可或缺的一部分。而作为最大的社交媒体平台之一&#xff0c;Facebook一直在前沿探索数字社交的边界&#xff0c;并且不断塑造着未来社交媒体的发展趋势。本文将深入探讨Facebook在数字社交领域的探索与创新&#xff0…

RDGCN阅读笔记

Relation-Aware Entity Alignment for Heterogeneous Knowledge Graphs 面向异质知识图谱的关系感知实体对齐 Abstract 实体对齐是从不同的知识图(KGs)中链接具有相同真实世界实体的任务&#xff0c;最近被基于嵌入的方法所主导。这种方法通过学习KG表示来工作&#xff0c;以…