python解法:leetcode 39 Combination Sum 回溯加剪枝

版权声明:转载请说明链接~~~ https://blog.csdn.net/weixin_40546602/article/details/88357837

下面详细介绍 39. Combination Sum 和 40. Combination Sum II 的python解法,主要用到了回溯加剪枝的思想。

leetcode 39

Given a set of candidate numbers (candidates(without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.  每个数字可以使用多次

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations. 允许给出重复的解决方案不

Example 1:

Input: candidates = [2,3,6,7], 
target = 7,
A solution set is:
[
  [7],
  [2,2,3]
]

Example 2:

Input: candidates = [2,3,5], 
target = 8,
A solution set is:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

解法:

递归函数 dfs(candidates,sublist,target,last),其中sublist记录当前满足条件的子数组,last为当前子数组的最后一个元素。

剪枝操作1:目标值小于元素数组的最小元素,则无需继续遍历

剪枝操作2:当前元素大于目标值,则后续元素一定大于目标值(数组已排序),不会满足条件,无需继续遍历

剪枝操作3:若当前数值小于当前sublist的最后一个元素,则继续遍历,防止出现重复解决方案,如[2,2,3],[3,2,2]

class Solution(object):
    def combinationSum(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        self.res = []
        if len(candidates) <= 0:
            return res
        candidates.sort()
        self.dfs(candidates,[],target,0)  # 递归回溯
        return self.res
            
    def dfs(self,candidates,sublist,target,last):  # last表示当前sublist的最后一个元素
        if target == 0:
            self.res.append(sublist) 
        if target < candidates[0]:  # 剪枝操作,目标值小于拥有的最小元素
            return 
        for num in candidates:  # 数字可重复使用,则每次从头遍历
            if num > target:  # 剪枝操作,当当前数值大于目标值,则后续无需遍历
                return 
            if num < last: # 剪枝操作:若当前数值小于当前sublist的最后一个元素,则继续遍历,防止出现重复解决方案,如[2,2,3],[3,2,2]
                continue
            self.dfs(candidates,sublist+[num],target-num,num)
   

leetcode 40 和leetcode39的主要差别在于,给定的数组中有重复的元素;但是在解决方案中不允许重复使用数字。

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

Each number in candidates may only be used once in the combination.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

Example 1:

Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

Example 2:

Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
  [1,2,2],
  [5]
]

解法:

回溯递归函数dfs(self,candidates,sublist,target,index),index为当前遍历到数组的位置,因为不允许重复使用元素,只可依次遍历。

剪枝操作1: 当target值已经小于0,由于数组中包含负数,所有之间返回

剪枝操作2:保证每个数字只使用一次

class Solution(object):
    def combinationSum2(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        # 回溯加剪枝
        if len(candidates)<=0:
            return []
        candidates.sort()
        self.res = []
        self.dfs(candidates,[],target,0)
        return self.res
    def dfs(self,candidates,sublist,target,index):
        if target == 0:
            self.res.append(sublist)
            return
        if target < 0:
            return
        for i in range(index,len(candidates)):  # 从当前index开始遍历
            if i != index and candidates[i] == candidates[i-1]: # 保证每个数字只使用一次
                continue
            self.dfs(candidates,sublist+[candidates[i]],target-candidates[i],i+1)

猜你喜欢

转载自blog.csdn.net/weixin_40546602/article/details/88357837
今日推荐