40. 组合总和 II
题目来源:
leetcode题目:40. 组合总和 II - 力扣(LeetCode)
解题思路:
方法一:选或者不选当前元素,通过提前获得后续元素的和来减枝,但是还是超过时间限制。
方法二:利用数组对所给集合进行预处理,存储 每个数字的出现次数,然后通过选不选当前元素来进行遍历。
解题代码:
#python3
#超出时间限制
class Solution:res=[]follows=[]def dfs(candidates:List[int],target:int,pos:int,chosen:List[int]):if pos>=len(candidates):return if Solution.follows[pos]<target:return newChosen=copy.deepcopy(chosen)#不选择该元素Solution.dfs(candidates,target,pos+1,newChosen) #选择该元素newChosen.append(candidates[pos])temp=target-candidates[pos]if temp==0:Solution.res.append(newChosen)elif temp>0 and pos+1<len(candidates) and temp<=Solution.follows[pos+1]:Solution.dfs(candidates,temp,pos+1,newChosen)else:return def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:#初始化Solution.res=[]candidates.sort()Solution.follows=[0]*len(candidates)Solution.follows[len(candidates)-1]=candidates[len(candidates)-1]for i in range(len(candidates)-2,-1,-1):Solution.follows[i]=Solution.follows[i+1]+candidates[i]#计算Solution.dfs(candidates,target,0,[])#去重Solution.res.sort()reRes=[]if len(Solution.res)==0:return []else:reRes.append(Solution.res[0])for result in Solution.res:if result!=reRes[len(reRes)-1]:reRes.append(result)return reResreturn Solution.res
#python3
class Solution:res=[]def getAnswer(cnt:List[int],target:int,pos:int,chosen:List[int]):if target==0:Solution.res.append(chosen)elif target<0:return if pos>len(cnt):returnif pos>target: #已超出return #选择x个for i in range(0,cnt[pos]+1):newChosen=copy.deepcopy(chosen)newTarget=target-i*posfor j in range(0,i):newChosen.append(pos)Solution.getAnswer(cnt,newTarget,pos+1,newChosen)def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:Solution.res=[]cnt=[]for i in range(0,51):cnt.append(0)for i in range(len(candidates)):cnt[candidates[i]]=cnt[candidates[i]]+1Solution.getAnswer(cnt,target,1,[])return Solution.res
总结:
官方题解也是一样的思路,不过他存储用的哈希表。