繁体   English   中英

为什么在递归问题中使用 list.pop() 和 list = list[:-1] 时得到不同的结果

[英]Why get different results, when using list.pop() and list = list[:-1] in recursive problem

我正在尝试使用递归方法来解决 Leetcode 上的“组合和”问题。

组合和问题

  1. 给定一组不同的candidates整数和一个目标整数target ,返回所有唯一candidates组合的列表,其中所选数字的总和为target 您可以按任何顺序返回组合。
  2. 可以从candidates无限次选择相同的号码。 如果所选数字中至少一个的频率不同,则两种组合是唯一的。 例子
Input: candidates = [2,3,5], target = 8 Output: [[2,2,2,2],[2,3,3],[3,5]]

当我使用 "c = c[:-1]" 去掉 "c" 的结束元素时,我无法得到正确的结果。 然而,在我用“c.pop()”替换“c = c[:-1]”之后,结果就对了。

看完这篇文章,我的理解是

  1. “list.pop()”将对原始列表进行更改,而“list[:-1]”将创建一个新列表。
  2. "list.pop()" 和 "list=list[:-1]" 将得到相同的结果

但是在我的递归方法中,很明显,“list=list[:-1]”没有完成工作。 我想知道为什么在递归函数中“list.pop”和“list=list[:-1]”之间存在差异。 为什么 list=list[:-1] 在递归方法中会出错?

这是我的代码:

"""
def findCombination(self, nums: List[int], target: int,
                    index: int, c: List[int],
                    res: List[List[int]]):
"""
def findCombination(nums, target, index, c, res):
    if target <= 0:
        if target == 0:
            res.append(c.copy())
        return
    for i in range(index, len(nums)):
        if nums[i] > target:
            break
        c.append(nums[i])
        print(f"self.findCombination({nums}, {target - nums[i]}, {i}, {c}, {res})")
        findCombination(nums, target - nums[i], i, c, res)
        c.pop()
        # c = c[:-1]

if __name__ == "__main__":
    candidates = [2, 3, 5]
    target = 5
    c, res = [], []
    findCombination(candidates, target, 0, c, res)
    print(f"Combinations: {res}")
"""
Using c.pop()
---------------------
self.findCombination([2, 3, 5], 3, 0, [2], [])
self.findCombination([2, 3, 5], 1, 0, [2, 2], [])
self.findCombination([2, 3, 5], 0, 1, [2, 3], [])
self.findCombination([2, 3, 5], 2, 1, [3], [[2, 3]])
self.findCombination([2, 3, 5], 0, 2, [5], [[2, 3]])
Combinations: [[2, 3], [5]]

Using c = c[:-1]
---------------------
self.findCombination([2, 3, 5], 3, 0, [2], [])
self.findCombination([2, 3, 5], 1, 0, [2, 2], [])
self.findCombination([2, 3, 5], 0, 1, [2, 3], [])
self.findCombination([2, 3, 5], 2, 1, [2, 3], [[2, 3]]) # Here, mistask, 2 didn't be popped
self.findCombination([2, 3, 5], 0, 2, [2, 5], [[2, 3]])
Combinations: [[2, 3], [2, 5]]
"""

在 Python 中,函数参数是通过引用传递的,所有变量都只是对内存中实际对象的引用。

list.pop()

改变引用指向的对象。

list=list[:-1]

将引用重定向到新对象。 它不会影响函数外的对象。

请记住=总是重定向引用。

a = [1] # reference to new object
b = a # reference to a
b.pop() # this changes a through b
print(a)
b = [1] # reference to new object, doesn't affect a anymore
print(a)

输出:

[]
[]

此示例代码突出显示了使用函数的差异

a = [1]
b = [1]

def f1(v):
    v.pop()
    print(v)
    # v is still a reference to a
    
def f2(v):
    # v is a reference to b
    v = v[:-1]
    # v is now a reference to a new object
    print(v)
    
print(a)
f1(a)
print(a)

print(b)
f2(b)
print(b)

输出:

[1]
[]
[]
[1]
[]
[1]

是正确的: b不是一个参考av是不参考ab 它们都是对内存中相同对象的引用。 b不会改变a b改变了a指向的对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM