110.平衡二叉树 (优先掌握递归)
再一次涉及到,什么是高度,什么是深度 平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1 。 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。 但leetcode中强调的深度和高度很明显是按照节点来计算的,如图: 关于根节点的深度究竟是1 还是 0,不同的地方有不一样的标准,leetcode的题目中都是以节点为一度,即根节点深度是1。但维基百科上定义用边为一度,即根节点的深度是0。 求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中) 。递归三部曲:
明确递归函数的参数和返回值 :参数:当前传入节点 。 返回值:以当前传入节点为根节点的树的高度 。
明确终止条件 :递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的树高度为0。
明确单层递归的逻辑 :如何判断以当前传入节点为根节点的二叉树是否是平衡二叉树呢?当然是其左子树高度和其右子树高度的差值。分别求出其左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则返回-1,表示已经不是二叉平衡树了。 如果左子树的高度计算结果为-1(意味着左子树不平衡 )或者右子树的高度计算结果为-1(意味着右子树不平衡 ),那么就直接返回-1
class Solution :
def get_height ( self, root) :
if not root:
return 0
left= self. get_height( root. left)
right= self. get_height( root. right)
if left == - 1 or right == - 1 or abs ( left - right) > 1 :
return - 1
return max ( left, right) + 1
def isBalanced ( self, root: Optional[ TreeNode] ) - > bool :
return self. get_height( root) != - 1
257. 二叉树的所有路径 (优先掌握递归)
要求从根节点到叶子的路径,所以需要前序遍历 ,这样才方便让父节点指向孩子节点,找到对应的路径。 第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。 先使用递归的方式,来做前序遍历。要知道递归和回溯就是一家的,本题也需要回溯。 递归:
递归函数参数以及返回值:要传入根节点,记录每一条路径的path,和存放结果集的result ,这里递归不需要返回值 :
确定递归终止条件 :本题要找到叶子节点,当 cur不为空,其左右孩子都为空的时候,就找到叶子节点。
确定单层递归逻辑 因为是前序遍历,需要先处理中间节点,中间节点就是我们要记录路径上的节点,先放进path中。 将 path 的一个副本(通过 path[:] 来创建,避免修改原始的 path )传递进去。
class Solution :
def traversal ( self, cur, path, result) :
if not cur:
return
path. append( cur. val)
if not cur. left and not cur. right:
result. append( '->' . join( map ( str , path) ) )
if cur. left:
self. traversal( cur. left, path[ : ] , result)
if cur. right:
self. traversal( cur. right, path[ : ] , result)
def binaryTreePaths ( self, root: Optional[ TreeNode] ) - > List[ str ] :
if not root:
return [ ]
result= [ ]
self. traversal( root, [ ] , result)
return result
404.左叶子之和 (优先掌握递归)
搞清楚什么是左叶子,剩下的就是二叉树的基本操作。 首先要注意是判断左叶子,不是二叉树左侧节点,所以不要上来想着层序遍历。 -左叶子的定义 : 节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点 。 判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。 递归三部曲:
确定递归函数的参数和返回值:判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和 。
确定终止条件:如果遍历到空节点,那么左叶子值一定是0 。
确定单层递归的逻辑:当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。 。
def sumOfLeftLeaves ( self, root: Optional[ TreeNode] ) - > int :
if not root:
return 0
if not root. left and not root. right:
return 0
leftvalue= self. sumOfLeftLeaves( root. left)
rightvalue= self. sumOfLeftLeaves( root. right)
if root. left and not root. left. left and not root. left. right:
leftvalue= root. left. val
return leftvalue + rightvalue
222.完全二叉树的节点个数(优先掌握递归)
需要了解,普通二叉树 怎么求,完全二叉树又怎么求
class Solution :
def countNodes ( self, root: TreeNode) - > int :
return self. getNodesNum( root)
def getNodesNum ( self, cur) :
if not cur:
return 0
leftNum = self. getNodesNum( cur. left)
rightNum = self. getNodesNum( cur. right)
treeNum = leftNum + rightNum + 1
return treeNum