美容美发网站模板服装定制设计公司
news/
2025/9/29 1:36:14/
文章来源:
美容美发网站模板,服装定制设计公司,广州地铁18号线,腾讯社交广告平台题目 给定两个整数 n 和 k#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案 提示#xff1a;假设 n5,k3 就是需要组合出来#xff0c;长度3且内容数据是在[1,n]这个区间内的所有可能得组合 同时一个组合里面内个数字只能出现一次#…题目 给定两个整数 n 和 k返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案 提示假设 n5,k3 就是需要组合出来长度3且内容数据是在[1,n]这个区间内的所有可能得组合 同时一个组合里面内个数字只能出现一次[1,2,3]、[3,2,1]、[2,1,3]...等这种只要里面的内容相同尽管顺序不否相同都认为是同一个组合 题解
说实话刚开始看到这个题不知道怎么下手看了看官方的题解大概理解了思路然后根据刚才理解的思路和自己的感觉慢慢摸索出最终的结果。 如果还有看了还不理解的同学可以先用官方的代码打印出来一个结果看是最终是要一个什么结果 比如我刚开始也看不明吧这个题目想干嘛然后我尝试用官方的代码打印出来 n5 k3 的结果 [[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] mCurNummIdxmCurNum// 判断当前的数组是否刚好塞满如果刚好塞满就可以将其插入到返回数组中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-aCurNum1 假设最大值n5 当前插入数字aCurNum4 此时5-412 表示还有2个数(4、5)可以使用// 然后加上数组已经插入的个数 aIdx 如果还不够填充数组那么后面的都不会满足条件if n-aCurNum1aIdx len(aSlice) {return}aSlice[aIdx] aCurNumif aIdx1 len(aSlice) {mTempSlice : make([]int, len(aSlice))copy(mTempSlice, aSlice)*aResult append(*aResult, mTempSlice)}// 如果数据还没填满继续进行数据填满了也会执行到这里会在里面的判断直接退出了execFunc(aResult, aSlice, aIdx1, aCurNum1, n)// 这里就考虑前面部分假设这里没有将这个值插入到数组中从而进行下个值的插入execFunc(aResult, aSlice, aIdx, aCurNum1, 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-aCurNum1aIdx k {return}mSlice[aIdx] aCurNumif aIdx1 k {mTempSlice : make([]int, k)copy(mTempSlice, mSlice)mResult append(mResult, mTempSlice)}mFunc(aIdx1, aCurNum1)mFunc(aIdx, aCurNum1)}mFunc(0, 1)return mResult
}提交记录 题目来源力扣题库 一点点笔记以便以后翻阅。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/921340.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!