Given an array of distinct不同的 integers candidates
and a target integer target
, return a list of all unique combinations of candidates
where the chosen numbers sum to target
. You may return the combinations in any order.
The same number may be chosen from candidates
an unlimited number of times. Two combinations are unique if the
frequency
of at least one of the chosen numbers is different.
The test cases are generated such that the number of unique combinations that sum up to target
is less than 150
combinations for the given input.
backtracking:
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
self.backtracking(candidates, target, 0, 0)
return self.result
def __init__(self):
self.result = []
self.path = []
def backtracking(self, candidates, target, total, startindex):
if total == target:
self.result.append(self.path[:]) # 忘记加[ : ]
return
if total > target:
return
for i in range(startindex, len(candidates)):
total += candidates[i]
self.path.append(candidates[i])
self.backtracking(candidates, target, total, i)
total -= candidates[i]
self.path.pop()
+ pruning branches:
1. candidates.sort()
2. if total + candidates[i] > target: #pruning (need sorting)
continue
class Solution:
def backtracking(self, candidates, target, total, startIndex, path, result):
if total == target:
result.append(path[:])
return
for i in range(startIndex, len(candidates)):
if total + candidates[i] > target: #pruning (need sorting)
continue
total += candidates[i]
path.append(candidates[i])
self.backtracking(candidates, target, total, i, path, result)
total -= candidates[i]
path.pop()
def combinationSum(self, candidates, target):
result = []
candidates.sort() # 需要排序
self.backtracking(candidates, target, 0, 0, [], result)
return result
Given a collection of candidate numbers (candidates
) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sum to target
.
Each number in candidates
may only be used once in the combination.
Note: The solution set must not contain duplicate combinations.
backtracking + pruning + duplicates condition:
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort() #不是 sorted
result = []
self.backtracking(candidates, target, [], result, 0, 0)
return result
def backtracking(self, candidates, target, path, result, startindex, total):
if total == target:
result.append(path[:])
return
if total > target:
return
for i in range(startindex, len(candidates)):
if total + candidates[i] > target: #不能直接>= ,if so, the equivalent situations are all skipped
continue
if i > startindex and candidates[i] == candidates[i - 1]: #so we add this step
continue
total += candidates[i]
path.append(candidates[i])
self.backtracking(candidates, target, path, result, i+1, total)
total -= candidates[i]
path.pop()
using used:
class Solution:
def backtracking(self, candidates, target, total, startIndex, used, path, result):
if total == target:
result.append(path[:])
return
for i in range(startIndex, len(candidates)):
# 对于相同的数字,只选择第一个未被使用的数字,跳过其他相同数字
if i > startIndex and candidates[i] == candidates[i - 1] and not used[i - 1]:
continue
if total + candidates[i] > target:
break
total += candidates[i]
path.append(candidates[i])
used[i] = True
self.backtracking(candidates, target, total, i + 1, used, path, result)
used[i] = False
total -= candidates[i]
path.pop()
def combinationSum2(self, candidates, target):
used = [False] * len(candidates)
result = []
candidates.sort()
self.backtracking(candidates, target, 0, 0, used, [], result)
return result
to optimise with target - candidates[i]:
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
results = []
self.combinationSumHelper(candidates, target, 0, [], results)
return results
def combinationSumHelper(self, candidates, target, index, path, results):
if target == 0:
results.append(path[:])
return
for i in range(index, len(candidates)):
if i > index and candidates[i] == candidates[i - 1]:
continue
if candidates[i] > target:
break
path.append(candidates[i])
self.combinationSumHelper(candidates, target - candidates[i], i + 1, path, results)
path.pop()
131. Palindrome Partitioning 分割回文串
Given a string s
, partition s
such that every substringof the partition is a palindrome. Return all possible palindrome /ˈpælɪnˌdroʊm/ partitioning /ˈpɑːrˌtɪʃənɪŋ/ of s
.
what does startindex mean? This startIndex is the cut line.
difficult !!!
how to find the end conditon!!!!!!!!!!
start_index == len(s) : cut already at the end . (total or sum(): all the numbers are used)
class Solution:
def partition(self, s: str) -> List[List[str]]:
result = []
self.backtracking(s, [], result, 0)
return result
def backtracking(self, s, path, result, startindex):
if startindex == len(s): # It's already cut to the end.
result.append(path[:])
return
for i in range(startindex, len(s)):
if s[startindex: i+1] == s[startindex: i+1][::-1]: #Determine if it is a palindrome
path.append(s[startindex: i+1])
self.backtracking(s, path, result, i+1)
path.pop() #最左边,截取第二个ab中的a的时候之后,回溯重新截取ab