首先复习下昨天的知识点,刷三道模板题增加点信心~
class Solution:
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
res , queue = [] , collections.deque()
queue.append(root)
while queue:
temp = []
for _ in range(len(queue)):
node = queue.popleft()
temp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(sum(temp) / len(temp))
return res
class Solution:
def largestValues(self, root: Optional[TreeNode]) -> List[int]:
res , queue = [] , collections.deque()
if not root:
return []
queue.append(root)
while queue:
temp = []
for _ in range(len(queue)):
node = queue.popleft()
temp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
Max = max(temp)
res.append(Max)
return res
N茶树的子节点是用列表存储的, 把二叉树的node.left 和 node.right改成node.children即可,遍历父节点的孩子节点,不为空的加入队列,别的和二叉树的层序遍历无异
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
res , queue = [] , collections.deque()
if root == None:
return []
queue.append(root)
while queue:
temp = []
for _ in range(len(queue)):
node = queue.popleft()
temp.append(node.val)
for child in node.children:
if child != None:
queue.append(child)
res.append(temp)
return res
class Solution:
def swap(self,node):
if node == None:
return node
temp = node.left
node.left = node.right
node.right = temp
self.swap(node.left)
self.swap(node.right)
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
self.swap(root)
return root
翻转二叉树,思路是遍历这棵树的同时,交换当前节点的左右孩子
推荐使用前序遍历或后序遍历,注意:交换的是指针,而非节点值
当然,本题层序也能做:
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
queue = collections.deque([root])
if not root:
return None
while queue:
temp = []
for _ in range(len(queue)):
node = queue.popleft()
temp.append(node)
node.left , node.right = node.right , node.left
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
优先掌握层序和前序遍历
写了很多遍层序遍历之后,其实这题第一反应是用层序遍历+双指针。
思路是层序遍历的同时,将左右孩子节点值加入temp数组中,逐层判断这一层是否是对称的,遍历结束若还没False,就return True,当遇到左右孩子为空时,人为的往temp中加入一个数(比如999),代表此为空,以保证temp数组的长度等于2^k。
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
queue = collections.deque([root])
if not root:
return False
while queue:
temp = []
for _ in range(len(queue)):
node = queue.popleft()
if node.left:
temp.append(node.left.val)
queue.append(node.left)
else:
temp.append(999)
if node.right:
temp.append(node.right.val)
queue.append(node.right)
else:
temp.append(999)
l , r = 0 ,len(temp) - 1
while l < r:
if temp[l] != temp[r]:
return False
else:
l += 1
r -= 1
return True
temp append 999是因为0,1这样的数会跟二叉树中的节点值混淆,影响结果
当然,卡哥讲的后序遍历也要掌握,思路如下:
首先,最重要的一点感性认知:要判断使用哪种遍历方式,本题要判断是否对称,显然要先递归的查看左子树和右子树是否对称,再返回给上一层节点结果。这就要求必须使用后续遍历,左右中的顺序才能做到。
class Solution:
def compare(self,left,right):
#递归出口
if left == None and right != None: return False
elif left != None and right == None: return False
elif left == None and right == None: return True
elif left.val != right.val: return False
#其余情况即为:左右都不为空,且值相等,那么就递归调用,往下一层遍历
else:
outside = self.compare(left.left , right.right)
inside = self.compare(left.right , right.left)
#调用函数,递归的比较,返回结果
isSame = outside and inside
return isSame
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
return self.compare(root.left , root.right)
说实话,这个方法理解有点困难,总之就是不断地递归遍历,比较二叉树左右子树的外侧是否相等,内侧是否相等、、
LC104 二叉树的最大深度
区分深度和高度:
- 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
- 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
高到底,深到顶。求高度,用后序;求深度,用前序。根据定义,根节点的高度,即为树的最大深度。
class Solution:
def func(self,node):
#递归出口
if node == None:
return 0
#单层处理逻辑
leftheight = self.func(node.left)
rightheight = self.func(node.right)
depth = 1 + max(leftheight , rightheight)
#当前节点的高度就是1+孩子节点高度的较大的那个
return depth
def maxDepth(self, root: Optional[TreeNode]) -> int:
return self.func(root)
这道题层序遍历的时间复杂度更好
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if root == None:
return 0
queue = collections.deque([root])
count = 0
while queue:
for _ in range(len(queue)):
node = queue.popleft()
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
count += 1
return count
递归法解答如下,跟最大深度还是有一定区别的
class Solution:
def getDepth(self, node):
if node is None:
return 0
leftDepth = self.getDepth(node.left) # 左
rightDepth = self.getDepth(node.right) # 右
# 当一个左子树为空,右不为空,这时并不是最低点
if node.left is None and node.right is not None:
return 1 + rightDepth
# 当一个右子树为空,左不为空,这时并不是最低点
if node.left is not None and node.right is None:
return 1 + leftDepth
result = 1 + min(leftDepth, rightDepth)
return result
def minDepth(self, root):
return self.getDepth(root)