40. 组合总和 II

40. 组合总和 II

题意

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

  • 所有数字(包括目标数)都是正整数。

  • 解集不能包含重复的组合。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

解题思路

  1. 在循环中处理下一步,这样就不用在一开始的时候选择元素;

  2. 维护是否放过该下标对应的数字的数组,如果已经访问过,则不将其加入路径数组中;

  3. 在3点基础上改进的,思想和1是一样的;

实现

class Solution(object):
def combinationSum2(self, candidates, target):
       """
      :type candidates: List[int]
      :type target: int
      :rtype: List[List[int]]
      """
       def dfs(cur, start, path, res):
           if cur == 0:
               res.append(path) # reach good leaf
               return
           for i in xrange(start, len(candidates)):
            # 这里是啥意思??
               if i > start and candidates[i] == candidates[i - 1]:
                   continue
               if candidates[i] > cur:
                   break
               dfs(cur - candidates[i], i + 1, path + [candidates[i]], res)
       
       res = []
       candidates.sort()
       dfs(target, 0, [], res)
       return res
     
def combinationSum2(self, candidates, target):
       """
      :type candidates: List[int]
      :type target: int
      :rtype: List[List[int]]
      """
       res = []
       nums_len = len(candidates)
       # 记录下对应下标的数字是否访问过,保证每个数字只被使用一次
       visited = [False] * nums_len
       candidates.sort()

       def helper(index, target, path):
           # 边界条件为剩余关键字减到了0,表明path中的值的和已经满足条件
           if not target:
               if path not in res:
                   res.append(path)
               return
           
           for idx in range(index, nums_len):
               # 如果剩余关键字比当前数字还要小的话,后面就没有循环的必要了
               # 所以从idx后面的继续找;
               if visited[idx]:
                   continue
               if target >= candidates[idx]:
                   visited[idx] = True
                   helper(idx, target - candidates[idx], path + [candidates[idx]])
                   visited[idx] = False
               else:
                   break
       
       helper(0, target, [])
       return res

def combinationSum2(self, candidates, target):
       """
      :type candidates: List[int]
      :type target: int
      :rtype: List[List[int]]
      """
       res = []
       nums_len = len(candidates)
       # 记录下对应下标的数字是否访问过,保证每个数字只被使用一次
       candidates.sort()

       def helper(index, target, path):
           # 边界条件为剩余关键字减到了0,表明path中的值的和已经满足条件
           if not target:
               if path not in res:
                   res.append(path)
               return
           
           for idx in range(index, nums_len):
               # 如果剩余关键字比当前数字还要小的话,后面就没有循环的必要了
               # 所以从idx后面的继续找;
               if target >= candidates[idx]:
                   helper(idx+1, target - candidates[idx], path + [candidates[idx]])
               else:
                   break
       
       helper(0, target, [])
       return res

posted @ 2017-08-19 11:43  banananana  阅读(109)  评论(0编辑  收藏  举报