日常刷题之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 不可能大于 n
	mResult := 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 := 1
	if mCurNum > n {
		// 当前使用的数字已经超了规定,直接退出就行
	}

	if mIdx >= k {
		// 已经超过数组的长度了,后面的都不用算了,直接可以退出了
	}

	// 后续这里还可以提前预判一波,判断后面剩余的长度能否塞满数组,不能的话也没必要继续下去了

	// 这里直接将这个数插入到数组中
	mSlice[mIdx] = mCurNum
	mIdx++
	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] = aCurNum

	if 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] = aCurNum

		if 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
}

提交记录

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


题目来源:力扣题库


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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows grep 安装及使用

1&#xff09;下载地址&#xff1a; Grep for Windows 2&#xff09;选择这个包下载&#xff1a; 3&#xff09; 将D:\Program Files (x86)\GnuWin32\bin目录 加入系统变量&#xff1a; 4&#xff09;grep "ACE_Lock_Adapter" -i * 执行命令如下&#xff1a;

使用Git仓库进行项目代码同步与打包

1. 引言 最近在用友的开发者中心论坛发现好多小伙伴反馈使用 YonStudio 开发工具进行云端项目导入失败的问题&#xff0c;有感于此问题会影响开发小伙伴的开发效率&#xff0c;特编写此文帮助新手小伙伴去规避这类问题的发生。 一直以来&#xff0c;开发者依循惯性思维去依赖…

不会搭建物联网数据平台的老板参考一下吧

搭建牛奶厂的物联网数据平台 对于现代牛奶厂&#xff0c;在数字化时代中&#xff0c;搭建物联网数据平台至关重要。这样的平台基础是建立IOT数据底座平台&#xff0c;它是支撑物联网应用的数据存储和管理基础设施&#xff0c;通常由分布式存储系统、时序数据库集群和存储管理组…

放弃 Rust 选择 Zig,Xata 团队推出 pgzx —— 计划使用 Zig 开发基于 PG 的分布式数据库

Summary Xata 公司在基于 PostgresSQL 开发自己的分布式数据库&#xff0c;出于 Zig 和 C 语言以及 PostgreSQL 的 API 有更好的互操作性的考虑&#xff0c;他们选择了 Zig 而非当红炸子鸡语言 Rust。他们的博客文章中对 pgzx 进行了介绍。让我们来看下他们对 Zig 和 Rust 语言…

学习网络编程No.15【高级IO之多路转接】

引言&#xff1a; 北京时间&#xff1a;2024/3/19/11:16&#xff0c;若是说记忆有克星的话&#xff0c;那么一定是时间。若是说耐心有克星的话&#xff0c;那么一定是人的心态。连续几天睡眠问题&#xff0c;加上环境影响&#xff0c;上篇博客还有部分知识只能放在该篇博客介绍…

面试总结:C++11新特性

对于C11的特性你了解多少&#xff1f;简单说说 - 在语法层面引入统一初始化&#xff08;即列表初始化&#xff09;&#xff0c;那么C11的初始化就可以分为列表初始化和字面值初始化 列表初始化就是使用{}&#xff08;花括号&#xff09;来进行对象、内置基本类型等的初始化 in…

超全整理,软件测试-性能测试流程汇总,看这一篇就够了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试&#xf…

这个插件,提供了1000多个在线底图服务!

本文推荐一下QGIS中的热门插件:QuickMapService。目前在QGIS插件市场下载量排名第一,先看下官网的介绍: Easy to use list of services and search for finding datasets and basemaps. 言简意赅,用来添加QGIS底图的插件。 插件安装 打开QGIS自带的插件管理器。 在搜索框中…

学习要不畏难

我突然发现&#xff0c;畏难心是阻碍我成长的最大敌人。事未难&#xff0c;心先难&#xff0c;心比事都难&#xff0c;是我最大的毛病。然而一念由心生&#xff0c;心不难时&#xff0c;则真难事也不再难。很多那些自认为很难的事&#xff0c;硬着头皮做下来的时候&#xff0c;…

黑马鸿蒙学习(3):滑动条

1&#xff09; 滑动条slidebar属性&#xff1a;

MySQL-1.数据库的基本操作

1. 数据库的基本操作 show databases; information_schema&#xff1a;信息图式&#xff0c;存储服务器管理数据库的信息 mysql&#xff1a;存放系统信息&#xff0c;用户名密码等 performance_schema&#xff1a;性能图式 sys&#xff1a;系统文件 1.1 创建数据库-studen…

[STL]priority_queue类及反向迭代器的模拟实现

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 今日主菜&#xff1a; priority_queue类及反向迭代器 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;c大冒险 向着c&…

【Web应用技术基础】HTML(5)——案例1:展示简历信息

样式&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>展示简历信息…

【微服务】Gateway

文章目录 1.基本介绍官方文档&#xff1a;https://springdoc.cn/spring-cloud-gateway/#gateway-starter1.引出网关2.使用网关服务架构图3.Gateway网络拓扑图&#xff08;背下来&#xff09;4.Gateway特性5.Gateway核心组件1.基本介绍2.断言3.过滤 6.Gateway工作机制 2.搭建Gat…

从姿态估计到3D动画

在本文中&#xff0c;我们将尝试通过跟踪 2D 视频中的动作来渲染人物的 3D 动画。 在 3D 图形中制作人物动画需要大量的运动跟踪器来跟踪人物的动作&#xff0c;并且还需要时间手动制作每个肢体的动画。 我们的目标是提供一种节省时间的方法来完成同样的任务。 我们对这个问题…

超实用!10条JavaScript这20年来增加的新功能?

部门捞人&#xff1a;前端可投&#xff1a;OD软件工程师社会招聘-表单-金数据 在过去的20年里&#xff0c;JavaScript经历了多次更新和升级&#xff0c;引入了许多新功能以增强其表达力、交互性和开发效率。以下是一些显著的新功能&#xff1a; 1.ECMAScript 6 (ES6) &#xf…

【ssh连接】奇奇怪怪报错记录

gitlab配置ssh连接&#xff0c;先跟着教程生成密钥&#xff0c;上传公钥&#xff0c;将服务器信息存入config文件&#xff0c;但是ssh连接超时&#xff0c;很急&#xff0c;想用服务器&#xff0c;各种搜索尝试&#xff0c;搞了两三天别的什么都没干&#xff0c;还是没解决&…

vue脚手架创建项目:账号登录(利用element-ui快速开发)(取消eslint强制格式)(修改端口号)

新手看不懂&#xff0c;老手不用看系列 文章目录 一、准备工作1.1 取消强制格式检查1.2 导入依赖&#xff0c;注册依赖 二、去element-ui官网找样式写Login组件2.1 引用局部组件2.2 运行项目 三、看一下发现没问题&#xff0c;开始修改前端的代码四、修改端口号4.1 修改后端端口…

中国赛道领跑之争:安踏将耐克越甩越远

一双鞋、一件衣服每被穿一次&#xff0c;消费者就会把它背后的品牌和自身的体验联系起来&#xff0c;做出评判。所以&#xff0c;如果说有什么领域能充分展示国产品牌的发展进步&#xff0c;鞋服一定包含在内&#xff0c;尤其是强调专业性的体育运动市场。 一年前的2023年3月&…

CSS3语法及选择器总结

CSS定义 css是一种样式表语言&#xff0c;用来美化HTML文档 一.CSS的引用 方式一:内部样式表(HTML中引用) 在HTML的title标签下方添加style双标签&#xff0c;style标签里面书写CSS *style里面的注释为/ * … / CSS的书写规则: 选择器{属性名&#xff1a;属性值&#xff…