LeetCode39 组合总和

LeetCode 第39题

问题描述

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

  • 所有数字(包括 target)都是正整数。
  • 解集不能包含重复的组合。

示例 1:

1
2
3
4
5
6
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]

示例 2:

1
2
3
4
5
6
7
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

解题思路

递归回溯法:

  1. 遍历candidates,计算target与每个数字num的余数
  2. 如果余数等于0,则将num添加到结果列表
  3. 否则,令target等于余数,跳转到第一步,从剩余数字(包括num)中查找target组合
  4. 如果target小于零,终止递归

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution:
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
if target < 0:
return None

result = []
for i in range(len(candidates)):
num = candidates[i]
r = target - num
if r == 0:
result.append([num])
combs = self.combinationSum(candidates[i:], r)
if combs:
for comb in combs:
comb.insert(0, num)
result.append(comb)
return result

本题可以先对candidates排序,当余数r小于零时,终止后面数字的遍历,从而降低时间复杂度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution:
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
# 对candidates进行排序
candidates.sort()
return self.__combinationSum(candidates, target)

def __combinationSum(self, candidates, target):
if target < 0:
return None

result = []
for i in range(len(candidates)):
num = candidates[i]
r = target - num
if r == 0:
result.append([num])
# 如果余数小于零,后续的数字都没必要进行遍历
if r < 0:
break
combs = self.combinationSum(candidates[i:], r)
if combs:
for comb in combs:
comb.insert(0, num)
result.append(comb)
return result
感谢你对我的支持,让我继续努力分享有用的技术和知识点