Leetcode 39: python可变类型复制(浅拷贝和深拷贝)
2017-08-01 16:41
260 查看
刚刚在leetcode上写了一道算法题:39. Combination Sum,因为踩了python中复制的坑,花了很长时间才爬出来=。=
起因是用python做完题后看了一下c++的解法:
用了回溯的方法,非常完美啊有没有,于是想用python改写这个算法
看起来是一模一样啊,可是得到的结果始终是:
debug了好久,终于发现是这里出现了问题:
这里相当于将
时,不仅会该改变
2.不在函数中直接修改
这种写法还隐式地实现了回溯,真是很巧妙啊!
题目:
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.
起因是用python做完题后看了一下c++的解法:
class Solution { public: std::vector<std::vector<int> > combinationSum(std::vector<int> &candidates, int target) { std::sort(candidates.begin(), candidates.end()); std::vector<std::vector<int> > res; std::vector<int> combination; combinationSum(candidates, target, res, combination, 0); return res; } private: void combinationSum(std::vector<int> &candidates, int target, std::vector<std::vector<int> > &res, std::vector<int> &combination, int begin) { if (!target) { res.push_back(combination); return; } for (int i = begin; i != candidates.size() && target >= candidates[i]; ++i) { combination.push_back(candidates[i]); combinationSum(candidates, target - candidates[i], res, combination, i); combination.pop_back(); } } };
用了回溯的方法,非常完美啊有没有,于是想用python改写这个算法
class Solution(object): def combinationSum(self, candidates, target): """ :type candidates: List[int] :type target: int :rtype: List[List[int]] """ def getComb(solution, candidates, index, target, res): if target < 0: return elif target == 0: res.append(solution) return for i in xrange(index, len(candidates)): if target < candidates[i]: break solution.append(candidates[i]) getComb(solution, candidates, i, target-candidates[i], res) solution.pop() candidates.sort() res = [] solution=[] getComb(solution, candidates, 0, target, res) return res
看起来是一模一样啊,可是得到的结果始终是:
[[],[]]
debug了好久,终于发现是这里出现了问题:
res.append(solution)
这里相当于将
solution直接复制到
res中,但是对象的引用并没有变,所以当执行
solution.append(candidates[i])
时,不仅会该改变
solution对象,同时也会改变
res,导致得不到想要的结果。
解决:
1.使用浅拷贝(因为这里的solution类型为
List[int],所以使用浅拷贝就OK啦):
s = copy.copy(solution) res.append(s)
2.不在函数中直接修改
solution,而是通过递归改变
solution的值:
class Solution(object):
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
def getComb(solution, candidates, index, target, res):
if target < 0:
return
elif target == 0:
res.append(solution)return
for i in xrange(index, len(candidates)):
if candidates[i] > target:
break
getComb(solution+[candidates[i]], candidates, i, target-candidates[i], res)
candidates.sort()
res = []
getComb([], candidates, 0, target, res)
return res
这种写法还隐式地实现了回溯,真是很巧妙啊!
相关文章推荐
- python可变类型vs不可变类型,深拷贝vs浅拷贝
- Python学习笔记——可变类型&不可变类型&深拷贝&浅拷贝
- Python中的可变,不可变对象;值类型,引用类型;浅拷贝,深拷贝理解
- 理解python可变类型vs不可变类型,深拷贝vs浅拷贝
- PYTHON实现将一个文件夹下的名字满足条件的图片拷贝复制到另一个文件夹路径
- Python的可变与不可变数据类型
- python 列表去重(不可变类型和可变类型)
- python中可变和不可变对象(复值,拷贝,函数值传递)
- Python(可变/不可变类型,list,tuple,dict,set)
- python中非序列类型期望值拷贝的解决方案
- Python 基础之字符串(不可变数据类型)
- python作用域的补充,局部引用全局作用域的修改尝试,可变类型内部可修改,内存指向不可变
- python列表复制(浅拷贝and深拷贝)
- python不可变类型和可变类型
- python的可变与不可变数据类型
- Python深复制浅复制or深拷贝浅拷贝
- 【LeetCode with Python】 Pascal's Triangle
- Python Cookbook 4.1 复制(拷贝)对象(浅复制和深复制)
- python list 的复制拷贝的简单介绍
- Python深复制浅复制or深拷贝浅拷贝