216.组合总和III

84 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情

216.组合总和III

题目分析

题目要求只使用数字1~9找出所有相加之和为n的k个数的组合,并且要求每个数字最多使用一次。这种组合问题是回溯的经典问题,所以我们也采用回溯算法来解决。

解题

这道题跟上一道组合题相比比较相似,本题多了一个限制条件,找到和为n的k个数的组合。所以我们也采取相同的方式,首先通过for循环横向遍历,通过递归纵向遍历。

接下来进行回溯三部曲:

  1. 递归函数的返回值和参数

递归的参数是下一层for循环搜索的起始位置,返回值为符合条件的结果。

  1. 回溯函数终止条件

当遍历到树的叶子节点时,也就是取到了k个元素后,就可以终止了。也就是当递归的深度等于限制条件k时,可以终止。

  1. 单层搜索的过程

单层循环就是向右横向遍历通过for循环,并且通过递归纵向遍历。注意在回溯结束后要将元素归位。

代码如下:

var combinationSum3 = function(k, n) {
    const backtrack = (start) => {
        const len = path.length
        if(len === k) {
            const sum = path.reduce((a,b) => a + b)
            if(sum === n) res.push([...path])          
             return
        }
        for(let i = start;i <= 9 - (k - len) + 1;i++) {
            path.push(i)
            backtrack(i + 1)
            path.pop()
        }
    }
    let res = [],path = []
    backtrack(1)
    return res
};

上面的代码当递归的深度等于k时,判断当前遍历的这条路线值的和是否等于限制条件,如果等于就返回。

同时上面的代码已经做了剪枝操作,当for循环遍历的元素大于限制条件目标和时,再往下遍历没有意义,可以进行剪枝。

总结

目前做的这两道回溯算法的题有很多一样的逻辑,理解起来并不是十分困难。