如何在LeetCode 中解决组合求和II(Combination Sum II)问题
2023-11-23 11:02:53
组合求和 II 是 LeetCode 中的一道经典题,它考察的是数组中元素组合求和的问题。给定一个数组 candidates 和一个目标和 target,要求找出数组中所有不重复的元素组合,使得这些元素组合的和等于 target。
这道题的难点在于数组中可能存在重复的元素,因此在求组合时需要考虑重复元素的情况。为了解决这个问题,我们可以使用回溯法来求解。回溯法的基本思想是,从数组的第一个元素开始,枚举所有可能的元素组合,如果某个元素组合的和等于 target,则将其加入结果集中。如果某个元素组合的和大于 target,则将其舍弃。如果某个元素组合的和小于 target,则继续枚举下一个元素。
def combinationSum2(candidates, target):
result = []
def backtrack(start, current_sum, combination):
if current_sum == target:
result.append(combination.copy())
return
if current_sum > target:
return
for i in range(start, len(candidates)):
# 跳过重复元素
if i > start and candidates[i] == candidates[i - 1]:
continue
combination.append(candidates[i])
backtrack(i + 1, current_sum + candidates[i], combination)
combination.pop()
candidates.sort()
backtrack(0, 0, [])
return result
除了回溯法,我们还可以使用动态规划来求解这道题。动态规划的基本思想是,将问题的子问题分解成更小的子问题,然后逐个解决这些子问题,最终得到问题的整体解。
def combinationSum2_dp(candidates, target):
dp = [[] for _ in range(target + 1)]
# 初始化
dp[0] = [[]]
for i in range(1, target + 1):
for candidate in candidates:
if i - candidate >= 0:
for combination in dp[i - candidate]:
# 跳过重复元素
if combination and candidate == combination[-1]:
continue
dp[i].append(combination + [candidate])
return dp[target]
这道题的难点在于数组中可能存在重复的元素,因此在求组合时需要考虑重复元素的情况。为了解决这个问题,我们可以使用回溯法或动态规划来求解。回溯法的基本思想是,从数组的第一个元素开始,枚举所有可能的元素组合,如果某个元素组合的和等于 target,则将其加入结果集中。如果某个元素组合的和大于 target,则将其舍弃。如果某个元素组合的和小于 target,则继续枚举下一个元素。
动态规划的基本思想是,将问题的子问题分解成更小的子问题,然后逐个解决这些子问题,最终得到问题的整体解。在解决组合求和 II 问题时,我们可以将子问题定义为:对于一个给定的目标和 target,有多少种不同的元素组合可以使它们的和等于 target。
我们可以使用一个二维数组 dp 来存储子问题的解。dp[i][j] 表示对于目标和为 i,有多少种不同的元素组合可以使它们的和等于 j。
我们