生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。人

随笔 - 151  文章 - 0  评论 - 117  阅读 - 108万 

 


题目描述

找出所有相加之和为 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
}
复制代码

 

 

posted on   测试开发喵  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示