102. 二叉树的层序遍历
题目描述: 102. 二叉树的层序遍历.
解法
层级法
class Solution(object):
def levelOrder(self, root):
if not root:
return []
res = []
st = collections.deque([root])
while st:
level = []
for _ in range(len(st)):
node = st.popleft()
level.append(node.val)
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
res.append(level)
return res
主要思想就是根据st的数量,向res中添加内容,并根据当前层向st加入node,这样每一次遍历st就都是这一层应有的node数量
递归
class Solution(object):
def leveltravel(self,node,level,res):
if not node:
return
if len(res) == level:
res.append([])
res[level].append(node.val)
self.leveltravel(node.left,level+1,res)
self.leveltravel(node.right,level+1,res)
def levelOrder(self, root):
res = []
self.leveltravel(root,0,res)
return res
递归的方法就是找共性,共性就是每个节点都有子节点,然后想找每一层的输出,他们的层数就是一样的,层数就对应着res的长度-1,只要左在前,每一层遍历的时候都一定会从左到右进行遍历,通过层数来控制插入值的位置,这样就不用考虑遍历和插值操作的先后顺序了。
107.二叉树的层次遍历 II
题目描述: 107.二叉树的层次遍历 II.
解法
层级法
class Solution(object):
def levelOrderBottom(self, root):
if not root:
return []
st = collections.deque([root])
res = []
while st:
level = []
for _ in range(len(st)):
node = st.popleft()
level.append(node.val)
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
res.append(level)
return res[::-1]
递归法
class Solution(object):
def leveltravel(self,node,level,res):
if not node:
return
if level == len(res):
res.append([])
res[level].append(node.val)
self.leveltravel(node.left,level+1,res)
self.leveltravel(node.right,level+1,res)
def levelOrderBottom(self, root):
res = []
self.leveltravel(root,0,res)
return res[::-1]
199.二叉树的右视图
题目描述: 199.二叉树的右视图.
解法
class Solution(object):
def rightSideView(self, root):
if not root:
return []
res = []
st = collections.deque([root])
while st:
for _ in range(len(st)):
node = st.popleft()
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
res.append(node.val)
return res
只需要输出每一层的最后一个就可以了
这道题好像不能用递归做
637.二叉树的层平均值
题目描述: 637.二叉树的层平均值.
解法
层级
class Solution:
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
if not root:
return []
st = collections.deque([root])
res = []
while st:
sum = 0
size = len(st)
for _ in range(size):
node = st.popleft()
sum += node.val
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
res.append(sum/size)
return res
迭代
class Solution:
def leveltravel(self,node,level,res):
if not node:
return
if len(res) == level:
res.append([])
res[level].append(node.val)
self.leveltravel(node.left, level+1, res)
self.leveltravel(node.right, level+1, res)
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
levels = []
res = []
self.leveltravel(root,0,levels)
for level in levels:
size = len(level)
sum = 0
for l in level:
sum+=l
res.append(sum/size)
return res
429.N叉树的层序遍历
题目描述: 429.N叉树的层序遍历.
解法
层级遍历
class Solution(object):
def levelOrder(self, root):
if not root:
return []
res = []
st = collections.deque([root])
while st:
level = []
for _ in range(len(st)):
node = st.popleft()
level.append(node.val)
for c in node.children:
st.append(c)
res.append(level)
return res
递归
class Solution(object):
def leveltravel(self,node,level,res):
if not node:
return
if level == len(res):
res.append([])
res[level].append(node.val)
for child in node.children:
self.leveltravel(child,level+1,res)
def levelOrder(self, root):
res = []
self.leveltravel(root,0,res)
return res
515.在每个树行中找最大值
题目描述: 515.在每个树行中找最大值.
解法
class Solution(object):
def largestValues(self, root):
if not root:
return []
st = collections.deque([root])
res = []
while st:
m = 0 - float('inf')
for _ in range(len(st)):
node = st.popleft()
m = m if m > node.val else node.val
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
res.append(m)
return res
116.填充每个节点的下一个右侧节点指针
题目描述: 116.填充每个节点的下一个右侧节点指针.
解法
class Solution(object):
def connect(self, root):
if not root:
return root
st = collections.deque([root])
while st:
pre = None
for _ in range(len(st)):
node = st.popleft()
if pre:
pre.next = node
pre = node
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
return root
117.填充每个节点的下一个右侧节点指针II
题目描述: 117.填充每个节点的下一个右侧节点指针II.
解法
lass Solution(object):
def connect(self, root):
if not root:
return root
st = collections.deque([root])
while st:
pre = None
for _ in range(len(st)):
node = st.popleft()
if pre:
pre.next = node
pre = node
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
return root
104.二叉树的最大深度
题目描述: 104.二叉树的最大深度.
解法
递归
class Solution(object):
def leveltravel(self,node,level):
if not node:
return level
return max(self.leveltravel(node.left,level+1),self.leveltravel(node.right,level+1))
def maxDepth(self, root):
return self.leveltravel(root,0)
层级迭代
class Solution(object):
def maxDepth(self, root):
if not root:
return 0
st = collections.deque([root])
level = 0
while st:
level += 1
for _ in range(len(st)):
node = st.popleft()
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
return level
111.二叉树的最小深度
题目描述: 111.二叉树的最小深度.
解法
递归(有问题)
class Solution(object):
def travel(self,node,level):
if not node:
return level
return min(self.travel(node.left,level+1),self.travel(node.right,level+1))
def minDepth(self, root):
return self.travel(root,0)
层级
class Solution(object):
def minDepth(self, root):
if not root:
return 0
st = collections.deque([root])
level = 0
while st:
level+=1
for _ in range(len(st)):
node = st.popleft()
if not (node.left or node.right):
return level
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
return level
226.翻转二叉树 (优先掌握递归)
226.翻转二叉树
题目描述: 226.翻转二叉树.
解法
递归前序遍历
class Solution(object):
def invertTree(self, root):
if not root:
return None
root.right, root.left = root.left, root.right
self.invertTree(root.left)
self.invertTree(root.right)
return root
迭代前序遍历
class Solution(object):
def invertTree(self, root):
if not root:
return root
st = [root]
while st:
node = st.pop()
node.left,node.right = node.right,node.left
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
return root
因为不需要访问具体的值,所以可以不用完全迭代
递归中序遍历
class Solution(object):
def invertTree(self, root):
if not root:
return root
self.invertTree(root.left)
root.right, root.left = root.left, root.right
self.invertTree(root.left)
return root
迭代中序遍历
class Solution(object):
def invertTree(self, root):
st = []
if root:
st.append(root)
while st:
node = st.pop()
if node.left:
st.append(node.left)
node.left, node.right = node.right, node.left
if node.left:
st.append(node.left)
return root
先压到栈中的应该是将来的右节点,而left则会变成将来的右节点,所以无论是迭代还是递归,都应先处理left,再考虑后面的right是否已经更新。
在遍历中则只需要考虑左右即可
递归后序遍历
class Solution(object):
def invertTree(self, root):
if not root:
return root
self.invertTree(root.left)
self.invertTree(root.right)
root.right,root.left = root.left, root.right
return root
迭代后序遍历
class Solution(object):
def invertTree(self, root):
st = []
if root:
st.append(root)
while st:
node = st.pop()
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
node.left, node.right = node.right, node.left
return root
层级
class Solution(object):
def invertTree(self, root):
if not root:
return root
que = collections.deque([root])
while que:
for i in range(len(que)):
node = que.popleft()
node.left,node.right = node.right, node.left
if node.right:
que.append(node.right)
if node.left:
que.append(node.left)
return root
因为是层级,所以不需要考虑左右节点谁先进队列,如果要求读取顺序,则需要考虑谁先进
101.对称二叉树
题目描述: 101.对称二叉树 .
解法
递归
class Solution(object):
def isSymmetric(self, root):
if not root:
return True
return self.compare(root.left,root.right)
def compare(self,left,right):
if left and not right:
return False
elif not left and right:
return False
elif not left and not right:
return True
elif left.val != right.val:
return False
out_side = self.compare(left.left,right.right)
in_side = self.compare(left.right,right.left)
return out_side and in_side
递归到底要考虑什么?考虑的是什么是相同的,要继续往下走,而这道题就是需要用后序遍历,遍历的内容是两个节点是否相同,也可以说两棵树是否相同,那如果两个节点的值相同,他们的子节点就不一定相同,那么就还是要先遍历子节点。
递归首先考虑边界情况,什么时候就可以返回值了?第二要考虑在每次递归里都做什么,什么是重复的部分?第三是考虑递归返回的值到底是什么?这样一来就可以写好一个递归的内容了。
使用栈
class Solution(object):
def isSymmetric(self, root):
if not root:
return True
st = [root.left,root.right]
while st:
r_node = st.pop()
l_node = st.pop()
if not r_node and not l_node:
continue
if not r_node or not l_node or r_node.val != l_node.val:
return False
st.append(l_node.left)
st.append(r_node.right)
st.append(l_node.right)
st.append(r_node.left)
return True
使用队列
class Solution(object):
def isSymmetric(self, root):
if not root:
return True
que = collections.deque([root.left,root.right])
while que:
l_node = que.popleft()
r_node = que.popleft()
if not l_node and not r_node:
continue
if not l_node or not r_node or l_node.val != r_node.val:
return False
que.append(l_node.left)
que.append(r_node.right)
que.append(l_node.right)
que.append(r_node.left)
return True
无论是栈或者是队列,都是暂时储存左右两个节点的,每次取出两个节点,检查这两个节点的相同关系。
层次
class Solution(object):
def isSymmetric(self, root):
if not root:
return True
levels = []
que = collections.deque([root.left,root.right])
while que:
level = []
if len(que)%2!=0:
return False
for _ in range(len(que)):
node = que.popleft()
if node:
que.append(node.left)
que.append(node.right)
level.append(node.val)
else:
level.append(None)
levels.append(level)
for level in levels:
if level != level[::-1]:
return False
return True
因为考虑到要看左右是否对称,因此就算节点是空的也要加到队列中,然后拿出每一层的节点是否和其反序相同。