返回

算法解惑:组合之妙,三数和为 n

前端

算法解析:组合三数和为 n

组合总和 III 算法旨在找出所有相加之和为 n 的 k 个数的组合,且这些数必须大于 0 且不重复。例如,对于 n = 7 和 k = 3,可能的组合包括 [1,2,4] 和 [1,3,3]。

动态规划方法

动态规划方法以一种自底向上的方式构建解决方案。首先,我们定义一个二维数组 dp,其中 dp[i][j] 表示相加之和为 j 的所有长度为 i 的组合的集合。

初始化:dp[0][0] = [[]]

递推关系:
    对于 i > 0:
        对于 j > 0:
            对于 l in range(1, min(j, i+1)):
                if j - l >= 0:
                    dp[i][j].extend([c + [l] for c in dp[i-1][j-l]])

回溯法

回溯法采用一种自顶向下的方式生成组合。它从一个空的组合开始,然后递归地将数字添加到组合中,直到满足以下条件:

  • 组合的长度达到 k
  • 组合的和等于 n
  • 最后一个添加到组合中的数字大于组合中最大的数字
def backtrack(nums, k, n, combination, result):
    if len(combination) == k and sum(combination) == n:
        result.append(combination.copy())
        return

    if len(combination) >= k or sum(combination) > n:
        return

    for i in range(len(nums)):
        combination.append(nums[i])
        backtrack(nums[i+1:], k, n, combination, result)
        combination.pop()

代码实现

def combinationSum3(k, n):
    # 初始化 dp 数组
    dp = [[[]] for _ in range(k+1)]

    # 填充 dp 数组
    for i in range(1, k+1):
        for j in range(1, n+1):
            for l in range(1, min(j, i+1)):
                if j - l >= 0:
                    dp[i][j].extend([c + [l] for c in dp[i-1][j-l]])

    # 返回结果
    return dp[k][n]

总结

组合总和 III 算法旨在找出所有相加之和为 n 的 k 个数的组合。我们可以使用动态规划或回溯法来求解此问题。动态规划方法的自底向上特性使其更易于理解,而回溯法的自顶向下方法提供了更大的灵活性。