题目描述
找出所有相加之和为 n
的 k
个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。
示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解释:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
没有其他符合的组合了。
示例 3:
输入: k = 4, n = 1
输出: []
解释: 不存在有效的组合。
在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。
提示:
2 <= k <= 9
1 <= n <= 60
题解
- 从1 -(10-k)分别作为第一个数字,递归向后求和,并记录求和路径为resi
- 定义x为当前要加的数字,n < x即目标总数小于当前要加的数字时,舍弃
- k == 0:还需要加的剩余数字数量为0时,舍弃
- 10-x < k:剩余可加的数字数量 小于 还需要加的剩余数字数量时,舍弃
- 和为预期n时,将路径中的相加的数字集合resi添加到目标数组res中
用递归的形式,
go代码:
func combinationSum3(k int, n int) [][]int {
var res [][]int
var resi []int
dp := func(k int, n int, x int, resi []int) {}
dp = func(k int, n int, x int, resi []int) {
/*n < x:目标总数小于当前要加的数字
或 k == 0:还需要加的剩余数字数量为0
或 10-x < k:剩余可加的数字数量 小于 还需要加的剩余数字数量时,
已不满足条件,直接return,无需再向后继续求和
*/
if n < x || k == 0 || 10-x < k {
return
}
resi = append(resi, x)
if n == x && k == 1{
/* 为什么要用copy,不直接append:
切片是一种类似的引用类型,原因是其存放数据的数组是通过指针间接引用的
*/
var dest = make([]int, len(resi))
copy(dest, resi)
res = append(res, dest)
return
}
for i := x+1 ; i < 10 ; i++ {
dp(k-1, n-x, i, resi)
}
}
// 从1 -(10-k)分别为第一个数字,往后求和
// 10-k:如果k=3,也就是需要3个数相加,那10-k=7,也就是只循环到7即可,
// 因为从7开始到9,正好是3个数,从8开始就只有两个数,不满足k=3需要3个数相加的条件
for i := 1 ; i <= 10-k ; i++ {
dp(k, n, i, resi)
}
return res
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律