实例变量差异Python

问题描述

我有两个关于以下解决方案的问题。

下面是我对这个 leetcode 问题的回答(解决方案 1):https://leetcode.com/problems/distribute-coins-in-binary-tree/

# Solution 1:
class Solution:
    def distributeCoins(self,root: TreeNode) -> int:
        self.ans = 0

        def dfs(node):
            if not node:
                return 0

            L,R = dfs(node.left),dfs(node.right)
            self.ans += abs(L) + abs(R)
            return node.val + L + R - 1

        dfs(root)
        return self.ans

问题 1 我想知道为什么下面不起作用。解决方案 1 和解决方案 2 的变量 ans 有什么区别?

# Solution 2:
class Solution:
    def distributeCoins(self,root: TreeNode) -> int:
        ans = 0  
        self.dfs(root,ans)
        return ans
    
    def dfs(self,node,ans):
        if not node:
            return 0

        L,R = self.dfs(node.left,ans),self.dfs(node.right,ans)
        ans += abs(L) + abs(R)

        return node.val + L + R - 1

因为下面(解决方案 3)对 grid 变量的更改会累积并影响所有递归,所以我认为解决方案 2 也是如此。

问题 2 解决方案 2 的 ans解决方案 3 的 grid 之间有什么区别,这使得由于递归引起的差异不会累积? (以下是 https://leetcode.com/problems/number-of-islands/解决方案)

# Solution 3:
class Solution:
    def numIslands(self,grid: List[List[str]]) -> int:
        if not grid:
            return 0

        count = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == '1':
                    self.dfs(i,j,grid)
                    count += 1

        return count

    def dfs(self,i: int,j: int,grid: List[List[str]]):
        if i < 0 or j < 0 or i >= len(grid) or j >= len(grid[0]) or grid[i][j] != '1':
            return

        grid[i][j] = '#'

        self.dfs(i + 1,grid)
        self.dfs(i - 1,grid)
        self.dfs(i,j - 1,j + 1,grid)

解决方法

在解决方案 #2 中,您将整数 ans 传递给 dfs 函数,该函数可能会更改它,但调用者看不到此更改,因为整数是不可变的,因此修改后的 ans 是一个新对象与原来的 ans=0 无关。

另一方面,解决方案#3,传递List,它是可变对象。更改(变异)此对象 grid[i][j] = '#' 可见于持有(引用)此对象的任何范围。

这与解决方案 #1 相同,它更改了 self.ans,这在所有递归范围内再次是同一对象的完全相同的属性。