日常刷题之77-组合

题目

给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案
提示:假设 n=5,k=3 就是需要组合出来,长度=3且内容数据是在[1,n]这个区间内的所有可能得组合
同时一个组合里面内个数字只能出现一次,[1,2,3]、[3,2,1]、[2,1,3]...等,这种只要里面的内容相同,尽管顺序不否相同都认为是同一个组合


题解

说实话,刚开始看到这个题,不知道怎么下手,看了看官方的题解,大概理解了思路,然后根据刚才理解的思路和自己的感觉慢慢摸索出最终的结果。
如果还有看了还不理解的同学,可以先用官方的代码打印出来一个结果,看是最终是要一个什么结果

比如我刚开始也看不明吧这个题目想干嘛,然后我尝试用官方的代码打印出来 n=5 k=3 的结果
[[1 2 3] [1 2 4] [1 2 5] [1 3 4] [1 3 5] [1 4 5] [2 3 4] [2 3 5] [2 4 5] [3 4 5]]

然后我就明白了,原来如此

开始动手写思路-思路1

虽然我已经看过了,知道要用递归,但是我在自己写的时候还是将复杂的东西拆分出来,拆成自己可以理解的,容易看懂且方便继续往下想的思路

func combine1(n int, k int) [][]int {// 根据题目可以确定 k 不可能大于 nmResult := make([][]int, 0)mSlice := make([]int, k)mIdx := 0// 判断当前的组合长度是否满足// 秉承一个条件,就是确定第一位是那个数字,后面的数字不能比第一个数字小// 然后就是枚举出所有可能的下一位数字的排序,一直重复这个想法// 当前的第一个数字确定mFirstNum := 1// 将这个数插入数组中mSlice[mIdx] = mFirstNum// 判断这个数组插入的数据是否已经满足足够的数量if mIdx == k-1 {// 满足,则将这个数组插入到结果集中mTempSlice := make([]int, k)copy(mTempSlice, mSlice)mResult = append(mResult, mTempSlice)}// 满足的后面就不用插入了,考虑不使用插入的最后这个数据,看是否可以继续替换别的数据继续进行return mResult
}
写到这里看是否合理-思路2

上面的代码片段写了后想了想,好像是可行的,既然是可行的,继续完善,当然这里我是知道最后是要用递归写的,所以后续写的思路会偏向递归的想法

func combine2(n int, k int) [][]int {mResult := make([][]int, 0)mSlice := make([]int, k)mIdx := 0// ==============================================// 当前使用到的数据mCurNum := 1if mCurNum > n {// 当前使用的数字已经超了规定,直接退出就行}if mIdx >= k {// 已经超过数组的长度了,后面的都不用算了,直接可以退出了}// 后续这里还可以提前预判一波,判断后面剩余的长度能否塞满数组,不能的话也没必要继续下去了// 这里直接将这个数插入到数组中mSlice[mIdx] = mCurNummIdx++mCurNum++// 判断当前的数组是否刚好塞满,如果刚好塞满就可以将其插入到返回数组中if mIdx == k {mTempSlice := make([]int, k)copy(mTempSlice, mSlice)mResult = append(mResult, mTempSlice)} else {// 是如果没有塞满,继续刚才的步骤,判断数字大小、数组长度、预判后续长度是否满足 ...}// 到这里就感觉好像中间部分的数据组合还有遗漏的,上面的部分只考虑到了替换 Slice[k] 这个位置数据,// 前面部分都是固定的,前面可能还有很多种组合没有实现// 这里就要考虑一下前面部分的,比如现在是第一个数,就不要 1 这个数字插入数组mIdx--// 前面选择的数字已经自增了,这里将数组的下表调回去,然后进行上面同样的判断计算// 先 判断数字大小、数组长度、预判后续长度是否满足 ...// ==============================================return mResult
}
答案的雏形-思路3

到这里代码应该怎么写的雏形已经出来了,然后以及哪些参数是需要进行传递的,心里大致都会有数了,然后进行代码填充

func execFunc(aResult *[][]int, aSlice []int, aIdx, aCurNum, n int) {if aCurNum > n {return}if aIdx >= len(aSlice) {return}// n-aCurNum+1 假设最大值n=5 当前插入数字aCurNum=4 此时5-4+1=2 表示还有2个数(4、5)可以使用// 然后加上数组已经插入的个数 aIdx 如果还不够填充数组那么后面的都不会满足条件if n-aCurNum+1+aIdx < len(aSlice) {return}aSlice[aIdx] = aCurNumif aIdx+1 == len(aSlice) {mTempSlice := make([]int, len(aSlice))copy(mTempSlice, aSlice)*aResult = append(*aResult, mTempSlice)}// 如果数据还没填满,继续进行(数据填满了也会执行到这里,会在里面的判断直接退出了)execFunc(aResult, aSlice, aIdx+1, aCurNum+1, n)// 这里就考虑前面部分,假设这里没有将这个值插入到数组中,从而进行下个值的插入execFunc(aResult, aSlice, aIdx, aCurNum+1, n)
}func combine3(n int, k int) [][]int {mResult := make([][]int, 0)mSlice := make([]int, k)execFunc(&mResult, mSlice, 0, 1, n)return mResult
}

到这里可以说是结束了,但是这递归方法的参数有点多,并且提交的运行结果内存占用并不是很满意,我想着官方的代码中用到了闭包,我感觉那种好像会省点内存,毕竟在go中方法的入参大部分都是值传递(可以理解为把传进来的参数复制了一份使用的)

另一种写法

在思路完全不变的情况下,使用上官方的套路看看,结果就是确实有点用

func combine4(n int, k int) [][]int {mResult := make([][]int, 0)mSlice := make([]int, k)var mFunc func(aIdx, aCurNum int)mFunc = func(aIdx, aCurNum int) {if aCurNum > n {return}if aIdx >= k {return}if n-aCurNum+1+aIdx < k {return}mSlice[aIdx] = aCurNumif aIdx+1 == k {mTempSlice := make([]int, k)copy(mTempSlice, mSlice)mResult = append(mResult, mTempSlice)}mFunc(aIdx+1, aCurNum+1)mFunc(aIdx, aCurNum+1)}mFunc(0, 1)return mResult
}

提交记录

在这里插入图片描述
在这里插入图片描述


题目来源:力扣题库


一点点笔记,以便以后翻阅。

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

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

相关文章

亮数据代理IP轻松解决爬虫数据采集痛点

文章目录 一、爬虫数据采集痛点二、为什么使用代理IP可以解决&#xff1f;2.1 爬虫和代理IP的关系2.2 使用代理IP的好处 三、亮数据代理IP的优势3.1 IP种类丰富3.1.1 动态住宅代理IP3.1.2 静态住宅代理IP3.1.3 机房代理IP3.1.4 移动代理IP 3.2 高质量IP全球覆盖3.3 超级代理服务…

Java标签提高for循环运行效率,减少资源开销

一&#xff0c;Java标签提高for循环运行效率,减少资源开销 少说先看代码再讲解 List<Long> lefts new ArrayList<>(); List<Long> rights new ArrayList<>(); lefts.add(0L); lefts.add(1L); lefts.add(2L); lefts.add(3L); lefts.add(4L); lefts.…

修改Linux系统时间与网络同步

文章目录 1、安装ntpdate2、修改时区3、设置系统时间与网络时间同步4、将系统时间写入硬件时间 1、安装ntpdate # Red Hat和Cent OS系统 sudo yum install ntpdate # 乌班图 sudo apt-get install ntpdate2、修改时区 1&#xff09;运行tzselect tzselect2&#xff09;选择A…

52、Qt/窗口、常用类、ui相关学习20240321

一、使用Qt 自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面。 要求&#xff1a; 1. 需要使用Ui界面文件进行界面设计 2. ui界面上的组件相关设置&#xff0c;通过代码实现 3. 需要添加适当的动图。 代码&#xff1a; #include "widget.h" #incl…

两台不同账号同一区域阿里云服务器如何实现内网互通?

登录阿里云平台 [开通peer对等] 点击右上角的控制台&#xff0c;然后进行搜索专有网络VPC。 点击进入专有网络VPC界面操作步骤如下&#xff1a; &#xff08;1&#xff09;点击VPC对等连接&#xff0c;然后开通VPC对等连接后创建对等连接。 &#xff08;2&#xff09;在另…

【计算机】——51单片机——持续更新

单片机是一种内部包含CPU、存储器和输入/输出接口等电路的集成电路&#xff08;IC芯片&#xff09; 单片机是单片微型计算机&#xff08;Single Chip Microcomputer&#xff09;的简称&#xff0c;用于控制领域&#xff0c;所以又称为微型控制器&#xff08;Microcontroller U…

038—pandas 重采样线性插补

前言 在数据处理时&#xff0c;由于采集数据量有限&#xff0c;或者采集数据粒度过小&#xff0c;经常需要对数据重采样。在本例中&#xff0c;我们将实现一个类型超分辨率的操作。 思路&#xff1a; 首先将原始数据长度扩展为 3 倍&#xff0c;可以使用 loc[] 方法对索引扩…

OpenCV4.9.0开源计算机视觉库安装教程

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 引言&#xff1a;OpenCV系列文章中的安装部分今天全部完成了&#xff0c;为了读者更方便阅读&#xff0c;大家可以按下列索引前往&#xff0c;成文较为仓促有错漏在所难免&#xff0c;欢迎大家指正…

【C#】使用C#窗体应用开启/停止Apache、MySQL服务

目录 一、前言 二、效果图 三、配置文件 四、代码 五、一键启动/停止所有服务 一、前言 使用C#窗体应用开启Apache、MySQL服务&#xff0c;不仅仅是Apache、MySQL&#xff0c;其他服务也可以使用同样的方法操作&#xff0c;包括开启自己写的脚本服务。 二、效果图 两种状…

JavaSE—IO流之字符流

&#x1f4cc; 字符流中的常用类及基本方法&#xff1a; 输入字符流 Reader输出字符流 Writer ○ Reader 的基本方法&#xff1a; • 读取一个字符并以整数的形式返回, 如果返回-1已到输入流的末尾。 int read() throws IOException • 读取一系列字符并存储到一个数组buff…

BufferedInputStream解读

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java之IO流啦&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好习惯&am…

继承和多态(2)(多态部分)

提前讲的重要知识点 一个类在没有父类的情况下默认有一个父类为Object类。 而当在有父类情况下&#xff0c;如果你那父类没有父类&#xff0c;则其父类的父类默认为object类&#xff0c;所以即使一个类有父类&#xff0c;其内部还是有object类。 object类都是隐藏起来的&…

【周总结】

周总结 完成项目混合版时区改造 完成相关jira问题的修改 完成老版本APP数据保存接口的兼容&#xff0c;手动赋值时区 2024/03/24 天气阴 一点不冷 1.Its time to go、Spring is coming&#xff01; 2. Its a nice day that staying with friends in a peaceful …

2024年云服务器ECS价格表出炉——腾讯云

腾讯云服务器多少钱一年&#xff1f;61元一年起。2024年最新腾讯云服务器优惠价格表&#xff0c;腾讯云轻量2核2G3M服务器61元一年、2核2G4M服务器99元一年可买三年、2核4G5M服务器165元一年、3年756元、轻量4核8M12M服务器646元15个月、4核16G10M配置32元1个月、312元一年、8核…

成功案例|全基因组测序+GWAS联合分析揭示不同种族帕金森病的遗传同质性和异质性

发表期刊&#xff1a;npj Parkinson’s Disease 影响因子&#xff1a;8.7 测序方式&#xff1a;WGS 研究对象&#xff1a;人 1 研究背景 帕金森病&#xff08;PD&#xff09;是一种常见的与年龄相关的神经退行性疾病&#xff0c;其特征是运动迟缓、姿势不稳定、僵硬和静息…

Redis中的过期键删除策略

过期键删除策略 概述 数据库键的过期时间都保存在过期字典中&#xff0c;并且知道根据过期时间去判断一个键是否过期,剩下的问题是&#xff1a;如果一个键过期了&#xff0c;那么它什么时候会被删除呢? 这个问题有三种可能的答案&#xff0c;它们分别代表了三种不同的删除策…

【linux】进程的地址空间

1.代码看现象引入 #include<stdio.h>#include<unistd.h>#include<string.h> #include<stdlib.h>int val100;int main (){ printf("i am father,pid:%d,ppid:%d,val:%d&#xff0c;&val:%p\n",getpid(),getppid(),val,&val);size_t…

vue2 和 vue3 配置路由有什么区别

vue2 和 vue3 配置路由有什么区别 初始化路由器实例&#xff1a;注入到应用中&#xff1a;动态路由参数和捕获所有路由&#xff1a;编程式导航 API&#xff1a;异步加载组件&#xff1a; vue2 如何 使用路由 第一步&#xff1a;安装 vue-router第二步&#xff1a;创建路由组件第…

【k8s】kubeasz 3.6.3 + virtualbox 搭建本地虚拟机openeuler 22.03 三节点集群 离线方案

kubeasz项目源码地址 GitHub - easzlab/kubeasz: 使用Ansible脚本安装K8S集群&#xff0c;介绍组件交互原理&#xff0c;方便直接&#xff0c;不受国内网络环境影响 拉取代码&#xff0c;并切换到最近发布的分支 git clone https://github.com/easzlab/kubeasz cd kubeasz gi…

<Linux> 模拟实现文件流 - 简易版

目录 1. FILE 结构设计 2、函数使用及分析 3、文件打开 fopen 4. 缓冲区刷新fflush 5. 数据写入fwrite 6. 文件关闭 fclose 7. 测试 8. 小结 1. FILE 结构设计 在设计 FILE 结构体前&#xff0c;首先要清楚 FILE 中有自己的缓冲区及冲刷方式 缓冲区的大小和刷新方式因…