[LeetCode] 39. 组合总和python实现

第一次跑去力扣刷题,就随便点进去了每日一题,题目是这样子的:

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

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:

输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:

输入:candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

提示:

1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate 中的每个元素都是独一无二的。
1 <= target <= 500

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我使用的python3.7。参考了这篇博客:https://www.cnblogs.com/eilearn/p/9485946.html

直接使用递归计算,一开始的代码:

class Solution:
    def combinationSum(self, candidates, target):
        ans_list = []       # 求解的答案
        ls = []             # 临时用的列表
        self.diguii(candidates=candidates, target=target, pos=0, sum0=0, temp_list=ls, ans_list=ans_list)
        return ans_list

    def diguii(self, candidates, target, pos, sum0, temp_list, ans_list):   # pos 是遍历位置, sum是当前的和, temp是列表
        if sum0 == target:   # 数据和等于目标值
            ans_list.append(temp_list)	# 记录符合要求的数据

            return

        if sum0 > target:    # 和超过了目标
            return

        for i in range(pos, len(candidates)):
            temp_list.append(candidates[i])     # 把第一个数放到列表
            sum0 += candidates[i]               # 求和
            self.diguii(candidates, target, i, sum0, temp_list, ans_list)     # 递归
            sum0 -= candidates[i]               # 减去上一个元素
            temp_list.pop()     # 去除列表最后一个元素

ans = Solution()
res = ans.combinationSum([2, 3, 6, 7], 7)
print(res)

思路没有错,但是得到的结果是

[[], []]

一开始以为是代码哪部分写错了,后面发现,python中列表的append方法是浅拷贝;我参考的方法使用的是c++中的容器vector,容器的方法都是深拷贝。由于我在最后使用了pop方法,所以得到的结果就只有空。

关于浅拷贝可以看一下这个或者自行百度。
https://zhuanlan.zhihu.com/p/161266559

在python中可以使用copy模块中的deepcopy函数进行深拷贝。

import copy

ls = [1, 2]
print(id(ls))       # 列表的地址
a = []
a.append(ls)
print(id(a[0]))     # 第一个元素的地址,与列表ls的地址相同
b = copy.deepcopy(ls)
print(id(b))        # 深拷贝之后地址不同

修改一下之前的代码,把浅拷贝改成深拷贝。

import copy


class Solution:
    def combinationSum(self, candidates, target):
        ans_list = []       # 求解的答案
        ls = []             # 临时用的列表
        self.diguii(candidates=candidates, target=target, pos=0, sum0=0, temp_list=ls, ans_list=ans_list)
        return ans_list

    def diguii(self, candidates, target, pos, sum0, temp_list, ans_list):   # pos 是遍历位置, sum是当前的和, temp是列表
        if sum0 == target:   # 数据和等于目标值
        	##################修改了这里####################
            temp_deepcopy = copy.deepcopy(temp_list)        # 深拷贝
            ans_list.append(temp_deepcopy)
            return

        if sum0 > target:    # 和超过了目标
            return

        for i in range(pos, len(candidates)):
            temp_list.append(candidates[i])     # 把第一个数放到列表
            sum0 += candidates[i]               # 求和
            self.diguii(candidates, target, i, sum0, temp_list, ans_list)     # 递归
            sum0 -= candidates[i]               # 减去上一个元素
            temp_list.pop()     # 去除列表最后一个元素

ans = Solution()
res = ans.combinationSum([2, 3, 6, 7], 7)
print(res)

运行结果:

[[2, 2, 3], [7]]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值