我正在解决LeetCode问题(link - click here)。基本上,问题是在给定的二叉树中找到所有路径。
考虑使用二叉树。
1 / \ 2 3 \ 5
我的工作解决方案如下 -
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def binaryTreePaths(self, root):
"""
:type root: TreeNode
:rtype: List[str]
"""
res = []
self.dfs(root, [], res)
a = []
for path in res:
a.append('->'.join([str(i) for i in path]))
return a
def dfs(self, root, ls, res):
if root == None:
return
ls = ls + [root.val]
if not root.left and not root.right: # if it is a leaf
res.append(ls)
if root.left:
self.dfs(root.left, ls, res)
if root.right:
self.dfs(root.right, ls, res)
上面提到的代码效果很好。但是有以下微妙的要点
ls = ls + [root.val]
后将ls.append(root.val)
更改为res
binaryTreePaths
,则dfs
变为[[],[]]
dfs
[[1,2,5],[1,3]]
中,我得到[[1,3],[1,3]]
而不是获得res
价值TextView
。这到底发生了什么?
答案 0 :(得分:1)
这是你的实现 - 没有不必要的类 - :
def dfs(root, ls, res):
if root == None:
return
ls = ls + [root.val]
if not root.left and not root.right:
res.append(ls)
if root.left:
dfs(root.left, ls, res)
if root.right:
dfs(root.right, ls, res)
这是输出
In [1]: tree = Node(1, Node(2, None, Node(5)), Node(3))
In [2]: res = []
In [3]: dfs(tree, [], res)
In [4]: res
Out[4]: [[1, 2, 5], [1, 3]]
大!有用。这是.append
:
def dfs(root, ls, res):
if root == None:
return
ls.append(root.val)
if not root.left and not root.right:
res.append(ls)
if root.left:
dfs(root.left, ls, res)
if root.right:
dfs(root.right, ls, res)
现在,这次......
In [7]: res = []
In [8]: dfs(tree, [], res)
In [9]: res
Out[9]: [[1, 2, 5, 3], [1, 2, 5, 3]]
不太好。请注意,两个列表共享所有内容......它几乎就像是相同的列表一样:
In [10]: [hex(id(r)) for r in res]
Out[10]: ['0x104285e88', '0x104285e88']
啊哈!他们是相同的列表!
第一个实现的原因是因为以下行:
ls + [root.val]
使成为新列表(这就是为什么你必须将其重新分配给ls
),而:
ls.append(root.val)
就地改变列表
In [20]: print(hex(id(x)))
0x104216288
In [21]: x.append(4)
In [22]: x
Out[22]: [1, 2, 3, 4]
In [23]: print(hex(id(x)))
0x104216288
但是看看当我们使用+
运算符时会发生什么:
In [24]: x = [1, 2, 3]
In [25]: print(hex(id(x)))
0x1042c8308
In [26]: x = x + [4]
In [27]: print(hex(id(x)))
0x104222588
如果我们先复制列表,我们可以使用append
In [29]: def dfs(root, ls, res):
...: if root == None:
...: return
...: copy = ls[:]
...: copy.append(root.val)
...: if not root.left and not root.right:
...: res.append(copy)
...: if root.left:
...: dfs(root.left, copy, res)
...: if root.right:
...: dfs(root.right, copy, res)
...:
In [30]:
In [30]: res = []
In [31]: dfs(tree, [], res)
In [32]: res
Out[32]: [[1, 2, 5], [1, 3]]
为了完整起见,使用扩充赋值运算符,例如some_list += another_list
就地修改了列表,基本上等同于some_list.extend(another_list)
In [38]: x = [1, 2, 3, 4]
In [39]: print(hex(id(x)))
0x1045e5d08
In [40]: x += [5]
In [41]: x
Out[41]: [1, 2, 3, 4, 5]
In [42]: print(hex(id(x)))
0x1045e5d08
答案 1 :(得分:0)
根据代码,ls
属于None类型,实际上不存在,因为您正在初始化它,因此它会给出.append
不存在的错误。 ls = ls + [root.val]
等于ls = [root.val]
。因此它有效。
希望这有帮助! :)