39. 组合总和
还算简单,与组合不同的地方在于可以重复使用。意思就是for循环中递归时start不后移。
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
res = []
def dfs(start, path, tar):
if tar < 0:
return
if tar == 0:
res.append(path[:])
return
for i in range(start, len(candidates)):
dfs(i, path + [candidates[i]], tar - candidates[i])
return
dfs(0, [], target)
return res
40.组合总和II
主要是去重逻辑。
单层遍历才需要去重。
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
res = []
candidates.sort()
def dfs(start, path, tar):
if tar < 0:
return
if tar == 0:
res.append(path[:])
return
for i in range(start, len(candidates)):
if i > start and candidates[i] == candidates[i - 1]: continue
dfs(i + 1, path + [candidates[i]], tar - candidates[i])
dfs(0, [], target)
return res
131.分割回文串
自己写了一版AC了,但是效率很低;
现在想明白华为笔试的题为什么通过率低了,就是因为没有优化。
class Solution:
def partition(self, s: str) -> List[List[str]]:
res = []
def dfs(path, remain):
if not remain:
res.append(path[:])
for i in range(len(remain)):
if self.check(remain[: i + 1]):
dfs(path + [remain[:i+1]], remain[i + 1:])
dfs([], s)
return res
def check(self, s):
return s == s[::-1]
优化版:
class Solution:
def partition(self, s: str) -> List[List[str]]:
res = []
n = len(s)
dp = [[False] * n for _ in range(n)]
for i in range(n):
dp[i][i] = True
for length in range(2, n + 1):
for i in range(n - length + 1):
j = i + length - 1
if s[i] == s[j]:
dp[i][j] = length == 2 or dp[i + 1][j - 1]
def dfs(path, start):
if start == n:
res.append(path[:])
return
for end in range(start, n):
if dp[start][end]:
dfs(path + [s[start:end + 1]], end + 1)
dfs([], 0)
return res
1277

被折叠的 条评论
为什么被折叠?



