LeetCode 77:组合
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
回溯算法:
def combine(n, k, res, route, startindex):
if len(route) == k:
res.append(route)
print(route)
return
for i in range(startindex, n+1):
route.append(i)
combine(n, k, res, route, i+1)
route.pop()
return res
上述写法得到的res为内容全部为空的列表,但print(route)得到的答案却是正确的
这是为什么呢?
将第三行代码改为如下形式,即可得到正确答案
res.append(route[:])
原来代码中的res.append(route),是将route直接加入res中,所以当route每一次发生变化时,res中每一个元素都会发生变化。
对route进行拷贝route[:],确保添加近res中的每一个数不再与参数route产生关联。
1、切片操作:a = route[:] 或者a = [each for each in route]
2、工厂函数:a = list(route)
3、copy函数:a = copy.copy(route)
route = [1, 2, ['a','b','c']]
a = route[:]
route[2].append('hhhhhh')
print(route,a)
>>>[1, 2, ['a', 'b', 'c', 'hhhhhh']] [1, 2, ['a', 'b', 'c', 'hhhhhh']]
以下代码来自于:
https://leetcode-cn.com/problems/combinations/solution/dfs-bfsliang-chong-fang-fa-python3ban-be-uylt/
class Solution:
def combine(self, n: int, k: int):
result = []
# DFS
# 已取的为temp 从剩下[cur..n]区间中取或不取数 直到temp有k个元素
def backtrack(temp, cur, n):
# 如果加上剩下的也取不够k个(之前不取的太多了) 直接剪枝
if len(temp) + n - cur + 1 < k:
return
# 如果已经取够了
if len(temp) == k:
result.append(temp)
return
# 不选取当前位置 (深度优先)
backtrack(temp, cur + 1, n)
# 选取当前位置
backtrack(temp + [cur], cur + 1, n)
backtrack([], 1, n)
return result
为什么这个不用copy,直接append?
欢迎交流讨论!