难度:Medium ?:982
题目
给定数组有重复数字,另外给定一个目标数值,求全部的数字组合,其加和为target。
注意:每个数字所用的次数不能大于它在数组里出现的次数。
思路
仍然用栈来做。(非递归解法)
对于stack中的一个元素:(i, path, remain)
i表示再往path里加数字时从哪个数字开始;往后遍历数组
如果remain<path[-1],那么这次终止;
如果candidate[i] == candidate[i-1],跳过i;
如果candidate[i] ==remain,往结果里加一个数组;
如果candidate[i] > remain,那么这次终止;
否则往stack中的一个元素:(i, path, remain)
注意:
- 将给定数组排序后,如果相邻的数字一样,需要跳过;
- 每次应该更新path用到了哪里的数字,下一轮从这后面开始,以保证数字被使用的次数不超过在数组里出现的次数。
解答
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
result = list()
stack = [(0,list(),target)]
cand_len = len(candidates)
while stack:
index,path,remain = stack.pop()
for i in range(index,cand_len):
if i>index and candidates[i] == candidates[i-1]:
continue
if path and remain < path[-1]:
break
if candidates[i] == remain:
result.append(path+[remain])
elif candidates[i] > remain:
break
else:
stack.append((i+1,path+[candidates[i]],remain-candidates[i]))
return result