回溯算法-组合总和 III

202 阅读2分钟

「这是我参与11月更文挑战的第30天,活动详情查看:2021最后一次更文挑战

Hope is a good thing, maybe the best of things. And no good thing ever dies.

前言

回溯算法是对树形或者图形结构执行一次深度优先遍历,实际上类似枚举的搜索尝试过程,在遍历的过程中寻找问题的解。

深度优先遍历有个特点:当发现已不满足求解条件时,就返回,尝试别的路径。此时对象类型变量就需要重置成为和之前一样,称为「状态重置」

题目

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明: 所有数字都是正整数。 解集不能包含重复的组合。 

示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]

示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]

思路分析

# 回溯算法-全排列# 回溯算法-全排列II的基础上,组合总和III 在条件上有给出了限制:

  1. 组合中只允许含有 1 - 9 的正整数
  2. 相加之和为 n 的 k 个数的组合

我们转化一下条件就是在[1,2,3,4,5,6,7,8,9]这个集合中找到和为nk个数的组合。

也就是 我们需要在 9 个数中选择 k 个数,让它们的和为 n

在 9 个数中选择 k 个数的组合枚举,对于枚举到的所有组合,判断这个组合内元素之和是否为 n

解题

/**
 * @param {number} k
 * @param {number} n
 * @return {number[][]}
 */
var combinationSum3 = function(k, n) {
    const temp = []; // 单个组合的数组
    const res = [];
    const dfs = (cur, n, k, sum) => {
        if (temp.length + (n - cur + 1) < k || temp.length > k) {
            return;
        }        
        if (temp.length === k && temp.reduce((previous, value) => previous + value, 0) === sum) {
            res.push(temp.slice());
            return;
        }
        temp.push(cur);
        dfs(cur + 1, n, k, sum);
        temp.pop();
        dfs(cur + 1, n, k, sum);
    }

    dfs(1, 9, k, n);
    return res;
};

附:leetcode-cn.com/problems/co…

结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。

文章如有错误之处,希望在评论区指正🙏🙏

欢迎关注我的微信公众号,一起交流技术,微信搜索 🔍 :「 五十年以后