层序遍历-part
1.102. 二叉树的层序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
levels = []
self.helper(root,0,levels)
return levels
def helper(self,node,level,levels):
if not node:
return
if len(levels) == level:
levels.append([])
levels[level].append(node.val)
self.helper(node.left,level + 1,levels)
self.helper(node.right,level + 1,levels)
利用递归操作进行解答,思路如下:1.判断根节点是否为空;2.按层遍历,题中代码比较难想到的部分是len(levels)==level,利用这个来区分层,思路很巧妙。levels是二维数组,里面包含的level是一维数组,将二维数组首先分配空间,然后在填充内部的数据。3.单层循环结束,左孩子右孩子思路相同,可以开始进行递归操作。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
queue = collections.deque([root])
result = []
while queue:
level = []
for _ in range(len(queue)):
cur = queue.popleft()
level.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result.append(level)
return result
利用队列进行解答,由于按层遍历是先进先出,可以想到队列,大体思路类似。
class Solution:
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
if not root:
return []
queue = collections.deque([root])
result = []
while queue:
level = []
for _ in range(len(queue)):
cur = queue.popleft()
level.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
sum1 = 0
for i in range(len(level)):
sum1 += level[i]
result.append(sum1/len(level))
return result
for循环可以再进行优化,在进行逐层添加是进行累计计算。
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
if not root:
return []
queue = collections.deque([root])
result = []
while queue:
level = []
for _ in range(len(queue)):
cur = queue.popleft()
level.append(cur.val)
for child in cur.children:
queue.append(child)
result.append(level)
return result
N叉树相比于二叉树不同的地方在于有多个孩子,所以在遍历的时候不能采用左右,而是需要利用for循环针对多个孩子逐个遍历。
class Solution:
def largestValues(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
queue = collections.deque([root])
result = []
while queue:
length = len(queue)
level = []
for i in range(length):
cur = queue.popleft()
level.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
result.append(max(level))
return result
直接利用python自带的max解决即可。
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return root
#此时queue长度为1,因为只有根节点进去
queue = collections.deque([root])
while queue:
length = len(queue)
#设置虚拟头结点
pre = None
for i in range(length):
node = queue.popleft()
if pre:
pre.next = node
pre = node
if pre.left:
queue.append(pre.left)
if pre.right:
queue.append(pre.right)
return root
巧妙设置虚拟头结点和当前节点,利用当前节点的前一个节点指向当前节点解题。题目逻辑和117同。
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
queue = collections.deque([root])
result = 0
while queue:
result += 1
for _ in range(len(queue)):
cur = queue.popleft()
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return result
理解好基础代码即可,while queue是逐层遍历,所以在层的地方进行累加计算。
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
queue = collections.deque([root])
result = 0
while queue:
result += 1
leng = len(queue)
for i in range(leng):
cur = queue.popleft()
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
if not cur.left and not cur.right:
return result
需要考虑有单个左孩子和右孩子情况,都不满足题意,排除即可。同时,题目中所要求的是深度,即为层数,不要统计为节点index。
226. 翻转二叉树
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
queue = collections.deque([root])
while queue:
leng = len(queue)
for _ in range(leng):
node = queue.popleft()
node.left, node.right = node.right, node.left
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
return root
仍旧是按照上面的思路采取层序遍历进行,仅进行了一下左右孩子的互换。
101. 对称二叉树
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return root
return self.compare(root.left,root.right)
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
outside = self.compare(left.left,right.right)
inside = self.compare(left.right,right.left)
result = outside and inside
return result
递归解题。
1.采用后序遍历-左右中。因为将左右孩子进行遍历后比较才能得出结论。
2.代码部分:首先是根节点的左右孩子进行比较,然后依次往下延伸,遍历到末尾在返回中,告诉父节点后父节点在进行结果返回。
compare函数中:1.if-elif,没有使用else的原因是终止情况还有一种,左右孩子不空且值相等。
2.内侧和外侧是基于整个数来定义的,outside和inside根据该定义写出。
3.result为两者相比较的bool返回值。