原题是:
思路是:
这个题前面所有题的不同之处在于,从上到下的过程中,需要上一层的值,
所以把上一层的值作为参数传入迭代函数。
这里本来作为参数传入的只有strs,而ans 尝试作为class变量,或者作为成员函数变量,都不可行,所以干脆也作为参数传入迭代函数,可以保证之前的值不丢失。
(后面发现作为ans作为helper函数的变量是可以的)
总之,下面的节点,需不需要上面的信息,是函数参数是否带入上一步结果的标准。
代码是:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
#ans = [] ----try one 写在这里的话,对不同的树所得到的所有结果都在ans中,
#因为是类变量。
def binaryTreePaths(self, root):
"""
:type root: TreeNode
:rtype: List[str]
"""
strs =""
ans =[]
if root == None:
return []
else :
return self.helper(root,strs,ans)
def helper(self,root,strs,ans):
#ans = [] 下一次调用helper时,前一次的结果就被清空了。
if root == None:
return ans
if root and not(root.left or root.right):
if not strs:
ans.append(str(root.val))
else:
ans.append(strs + "->" + str(root.val))
else:
strs = strs + "->" + str(root.val) if strs else str(root.val)
self.helper(root.left, strs, ans)
self.helper(root.right, strs, ans)
return ans
反思:
对比一下他人的代码,并修改了我自己的代码,发现了我在递归类代码中常犯的一类错误:
首先上别人的代码(感谢李颖友情赞助他的代码):
class Solution(object):
def helper(self, root, path): #---他思路传入参数的Path已经包含了调用函数的当前#节点,这点不重要
res = [] #-----重要的是,每层调用helper函数的节点,都有一个自己的res
#但是他 “回收”了上一层helper函数返回给这一层helper的res
if not root.left and not root.right:
res.append(path)
return res
if root.left:
lpath = path + '->' + str(root.left.val)
res += self.helper(root.left, lpath) #-----一个list + 另一个list = 一个合并了元
#素的List
if root.right:
rpath = path + '->' + str(root.right.val)
res += self.helper(root.right, rpath)
return res
def binaryTreePaths(self, root):
"""
:type root: TreeNode
:rtype: List[str]
"""
if not root:
return []
path = str(root.val)
return self.helper(root, path)
对比我的第一个版代码,我的上一层helper函数做了工作之后,没有在该层回收
所以导致最终的ans是空[]。
因此,我如果按照他的思路,修改自己的代码如下:
class Solution:
def binaryTreePaths(self, root):
"""
:type root: TreeNode
:rtype: List[str]
"""
strs =""
#ans =[]
if root == None:
return []
else :
#return self.helper(root,strs,ans)
return self.helper(root,strs)
#def helper(self,root,strs,ans):
def helper(self,root,strs):
ans = []
if root == None:
return ans
if root and not(root.left or root.right):
if not strs:
ans.append(str(root.val))
else:
ans.append(strs + "->" + str(root.val))
else:
strs = strs + "->" + str(root.val) if strs else str(root.val)
#self.helper(root.left, strs, ans)
#self.helper(root.right, strs, ans)
ans += self.helper(root.left,strs)
ans += self.helper(root.right,strs)
return ans
回想leetcode669,
我同样是犯了“没有回收上一层结果”的错误。
21,28两行,没有像23,24一样去回收成果。
对于测试例子[3-1-null-2]来说,范围是3-4,而错误代码,导致结果是[3-2],
原因是什么呢:
在函数trimBST处理1这个节点时,有一个属于1节点的root,他经过trim后,指向了2。但是当trimBST下一层,到处理2这个节点时,又有一个属于2节点的root,是同名的另一个存在,这个root经过trim指向了null,然而由于没有用1节点这一层的root去接收新的root(也就是Null),导致1这一层的root依然指向2节点。
正确的应该是:
多一点反思:
如果把669这个题,设置所有节点都在L-R范围以外(为避免选入无限循环)
在每一层直接返回下一层的结果,像这样:
可以顺利的把所有节点剪光。
是因为每一次下层的返回值,被这一层接收后,不经任何处理,直接上交上一层。
只有这样的时候,才可以这样写代码,直接返回递归函数的返回值