您的位置:首页 > 编程语言 > Python开发

Leetcode 39: python可变类型复制(浅拷贝和深拷贝)

2017-08-01 16:41 260 查看
刚刚在leetcode上写了一道算法题:39. Combination Sum,因为踩了python中复制的坑,花了很长时间才爬出来=。=

题目:

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


这种写法还隐式地实现了回溯,真是很巧妙啊!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: