110:平衡二叉树
平衡二叉树的定义是:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
那么也就是说,要使用一种遍历方法,先遍历两棵子树,然后再用这两个子树的高度做差,看看高度差是不是0 or 1。那就是要用后序遍历了。
class Solution:
def isBalanced(self,root):
def getHeight(node):
if not node:#判断终止条件
return 0
left_height=getHeight(node.left)#遍历左子树,得到高度
if left_height==-1:#如果是-1,就向上传递-1这个不是平衡二叉树的信息
return -1
right_height=getHeight(node.right)#同理左子树
if right_height==-1:#同理左子树
return -1
if abs(left_height-right_height)>1:#拿到左右子树的高度,做一下高度差的结果
return -1
else:
return max(left_height,right_height)+1#正常返回符合题目的高度
result=getHeight(root)#输入开始的地方~
if result!=-1:#做最终的结果判断
return True
else:
return False
这个题解里面。我们把-1当作“不是二叉树”的信息返回,就可以了。不用管具体是高度差了多少。先遍历左子树,拿到左子树的结果,无非两种情况(不是平衡二叉树:-1;是平衡二叉树:0,1),如果不是,向上返回这个信息,这里的向上返回是指,直接向上个递归返回这个子树就不是平衡二叉树。这样就不会执行后面的逻辑,一但是拿了个-1,那么永远是-1,这个-1的逻辑将永远向上传递,直到输出。那么,右子树也同理。
做题的时候乐乐一直有个问题,就是不加:
if left_height==-1:#如果是-1,就向上传递-1这个不是平衡二叉树的信息
return -1
和
if right_height==-1:#同理左子树
return -1
行不行。
答案是不行,也就是说,必须每次得到左右子树的是不是平衡二叉树的时候,都要向上返回,而不能,任意让他去执行下面综合左右子树高度差的逻辑。
if abs(left_height-right_height)>1:#拿到左右子树的高度,做一下高度差的结果
return -1
else:
return max(left_height,right_height)+1#正常返回符合题目的高度
因为这样少考虑了一种情况就是:
也就是说不能随便让进abs()中的逻辑,必须保证左子树和右子树都是符合平衡二叉树的规定才可以。如果左右子树不是平衡二叉树,那就直接向上返回就好了,不用走下面的逻辑。所以,必须左子树和右子树,得到他们的高度之后,有个判断,如果是-1,直接向上返回!
觉得这个题挺难的,但还是easy的评级,哎,是自己太菜了吧。
257:二叉树的所有路径
这个题需要进行回溯,回溯就是在递归之后紧接着一行,写回溯逻辑,一般是pop出数组值。
class Solution:
def binaryTreePaths(self,root):
path=[]
res=[]
def Traversal(node,path):
path.append(node.val)
if not node.left and not node.right:
res.append(path[:])
if node.left:
Traversal(node.left,path)
path.pop()
if node.right:
Traversal(node.right,path)
path.pop()
return res
if not root:
return res
res=Traversal(root,path)
new_path=[]
for i in range(len(res)):
new=""
for j in res[i]:
new=new+str(j)+"->"
new_path.append(new[:-2])
return new_path
关键:
if node.left:
Traversal(node.left,path)
path.pop()
if node.right:
Traversal(node.right,path)
path.pop()
中pop()操作!这样才能够完成1->2->5之后,把2,5弹出,在进入3,变成1->3。详细过程,等有空再画一个递归图应该就很明了了。
404:左叶子之和:
找到左叶子:
(1)该节点的左孩子和右孩子为空。
(2)该节点是其父节点的左孩子。
sum_total=0
def Traversal(node,sum_total):
if not node:
return 0
if not node.left and not node.right:
return 0
left_sum=Traversal(node.left,sum_total)
right_sum=Traversal(node.right,sum_total)
cur_left=0
if node.left and not node.left.left and not node.left.right:
cur_left=node.left.val
sum_total=left_sum+right_sum+cur_left
return sum_total
sum_total=Traversal(root,sum_total)
return sum_total
因为要收集一整棵二叉树的左叶子,所以,需要用后序遍历进行收集!先遍历左子树,在遍历右子树,收集两个子树的左叶子的和,然后中间的处理逻辑就是将当前几点都加起来,再向上返回左叶子的和。
总结:
觉得今天的题都好难啊,但都还是简单题,看来自己对递归的理解还是不能自如地去运用,才会觉得难吧。