39Combination Sum是说让我们在给定数组C中找到所有的组合,使得组合中数字的和是target值。并且组合里的数字可以重复,也就是不限制C中每一个数字的使用。
这明显是回溯啦,大家记得让你判断有多少种呢就是动态规划,一旦让我们写出全部的组合那就是回溯。
回溯就是一直加进去数,满足条件就存下来,不满足呢就回退一步。代码如下。注意backtracking函数,利用for可以实现回溯。还要注意for中一旦target<0,那么就代表着这个数组已经不可能和是target了,一定要设置break跳出这个循环,否则会一直进行下去,永无天日的!
class Solution(object):
def backtracking(self, candidates, target, start, val):
if target == 0:
Solution.re.append(val)
else:
for i in range(start,len(candidates)):
if target < 0:
break
self.backtracking(candidates,target-candidates[i],i,val+[candidates[i]])
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
Solution.re = []
self.backtracking(candidates,target,0,[])
return Solution.re
40Combination Sum II这道题跟上题区别不大,只是限制了每个数字只能使用一次,所以for的时候i的起始位置就不是每次都从第一个数字添加了,而是要后移的。并且这个为了结果的去重,必须先将C数组排序,然后回溯的时候是从小到大的。这里相对上一个加一个改进,就是将target<0这个操作变换为target
class Solution(object):
def backtracking(self, candidates, target, start, val):
if target == 0 and val not in Solution.re:
Solution.re.append(val)
else:
for i in range(start,len(candidates)):
if target < candidates[i]:
break
self.backtracking(candidates, target - candidates[i], i+1, val+[candidates[i]]);
def combinationSum2(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
candidates.sort()
Solution.re = []
self.backtracking(candidates, target, 0, [])
return Solution.re
216Combination Sum III是在II的基础上,把数组限制为了1-9 9个数字,然后结果的组合也必须是k个数字,和为n。这个的主要不同在于k个数字,其实也就是加个判断,大家不要慌。
class Solution(object):
def backtracking(self, k, n, start, val):
if k==0 and n ==0 :
Solution.re.append(val)
else:
for i in range(start,10):
if n < i :
break
self.backtracking(k-1,n-i,i+1,val+[i])
def combinationSum3(self, k, n):
"""
:type k: int
:type n: int
:rtype: List[List[int]]
"""
Solution.re = []
self.backtracking(k,n,1,[])
return Solution.re
377Combination Sum IV这道题是说给的数组中全是整数且没有重复,但是每个数字可以重复使用,让给出组合的总数,就不用给出所有的排列。沿用以上的方法当然可以啦,然后求个re的长度就行了。But他是会超时的,这就是我说的给出有多少种的时候就用动态规划。这个就是先建一个数组,大小就是目标值,意思就是target=1的时候有多少种,=2的时候有多少种,一直到=target。
class Solution(object):
def combinationSum4(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
dp = [0] *(target+1)
dp[0] = 1
for x in range(target+1):
for y in nums:
if x+y <=target:
dp[x+y] += dp[x]
return dp[target]