返回
算法解惑:组合之妙,三数和为 n
前端
2024-02-07 11:32:36
算法解析:组合三数和为 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 个数的组合。我们可以使用动态规划或回溯法来求解此问题。动态规划方法的自底向上特性使其更易于理解,而回溯法的自顶向下方法提供了更大的灵活性。