39. Combination Sum(Python3)

本文详细解析了组合总和问题的求解方法,利用深度优先搜索(DFS)递归算法,通过排序候选元素来减少不必要的遍历,最终找出所有可能的组合使元素之和等于目标值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

39. Combination Sum(Python3)

题目

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

The same repeated number may be chosen from C unlimited number of times.

Note:

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

For example, given candidate set [2, 3, 6, 7] and target 7,
A solution set is:

[
  [7],
  [2, 2, 3]
]

解题方案

思路:

  • 典型的DFS,使用递归效果最佳,如下图所示,为了减少遍历,需要将候选元素排序,当和大于target时则退出该层遍历
  • 这道题学习到了一点,就是python在写递归的时候一定要注意list值得传入,不能直接传入list本身,这样在下一层递归修改之后返回,回不到之前的list,这是由于python传入引用导致的
  • 解决办法就是新建一个值相同但是地址不同的变量,或者进行深拷贝,代码中之所以使用tmp+[cand[i]]而不使用tmp.append(cand[i])就是这个道理

这里写图片描述

代码:

class Solution:
    def combinationSum(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        def dfs(res,cand,target,index,tmp):
            for i in range(index,len(cand)):
                if sum(tmp) + cand[i] == target:
                    res.append(tmp+[cand[i]])
                elif sum(tmp) + cand[i] < target:
                    dfs(res,cand,target,i,tmp+[cand[i]])
                else:
                    return
        res = []      
        candidates.sort()
        dfs(res,candidates,target,0,[])
        return res

第二份代码,是指导我python的引用传入问题解决的

def combinationSum(self, candidates, target):
    res = []
    candidates.sort()
    self.dfs(candidates, target, 0, [], res)
    return res

def dfs(self, nums, target, index, path, res):
    if target < 0:
        return  # backtracking
    if target == 0:
        res.append(path)
        return 
    for i in xrange(index, len(nums)):
        self.dfs(nums, target-nums[i], i, path+[nums[i]], res)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值