leetcode 216 组合总和III

题目

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

  • 只使用数字1到9 每个数字
  • 最多使用一次

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

示例

输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。

解析

这道题和上一道组合问题很接近,只不过是多了一个终止条件,直接上回溯+剪枝的代码:

func combinationSum3(k int, n int) [][]int {
    //要找K个数的和为n
    var res [][]int
    var path []int
    sum := 0
    var backTrack func(int)
    backTrack = func(startIndex int) {
        //剪枝
        if sum > n || len(path) > k {
            return 
        }
        //递归终止条件
        if len(path) == k && sum == n {
            tmp := make([]int, k) //一样的原因
            copy(tmp, path)
            res = append(res, tmp)
            return
        }
        //单层递归循环+剪枝
        for i := startIndex; i <= 9-(k-len(path))+1; i++ {
            sum += i
            path = append(path, i)
            backTrack(i+1)
            //回溯
            sum -= i
            path = path[:len(path)-1]
        }
    }
    backTrack(1)
    return res
}

也可以将结果定义成函数外面的全局变量,然后在外定义函数;或者传数组的地址进来:

func combinationSum3(k int, n int) [][]int {
	res := [][]int{}
	path := []int{}
	sum := 0
	if n < 0 || n < 0 {
		return res
	}
	backTrackint(n, k, sum, 1, &path, &res)
	return res
}

func backTrackint(n, k, sum, startIndex int, path *[]int, res *[][]int) {
	if sum > n || len(*path) > k { // 第一个剪枝
		return
	}
	if sum == n && len(*path) == k {
		temp := make([]int, k)
		copy(temp, *path)
		*res = append(*res, temp)
		return
	}
	for i := startIndex; i <= 9-(k-len(*path))+1; i++ {
		*path = append(*path, i)
		sum += i
		backTrackint(n, k, sum, i+1, path, res) // 第二个错误,这里不能带星号,因为要递归调用这个函数
		sum -= i
		*path = (*path)[:len(*path)-1] // 第一个错误,这里需要用*path类型
	}
}

全局变量的:

var res [][]int
var path []int
var sum int
func combinationSum3(k int, n int) [][]int {
    res = [][]int{}
    if n < 0 || k < 0 {
        return res
    }
    brackTracing(n, k, 1, sum)
    return res
}

func brackTracing(n, k, startIndex, sum int) {
    if sum > n || len(path) > k { // 这个也算剪枝
        return
    }
    if sum == n && len(path) == k{
        temp := make([]int, k)
        copy(temp, path)
        res = append(res, temp)
    }

    for i := startIndex; i <= 9 - (k - len(path)) + 1; i++ { //注意这里是9,因为是从1-9中取,不剪枝的话直接就是i <= 9
        path = append(path, i)
        sum += i
        brackTracing(n, k, i+1, sum)
        path = path[:len(path)-1]
        sum -= i
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值