层序遍历
先自己试着做一道
102 二叉树的层序遍历
暴力遍历试试
写一半发现输入不是只有根节点啊,给了整个树的数组,但不是完全二叉树,没法用下标直接访问。。
不对啊,题意说的又是根节点,到底是啥。print了一下是根节点
虽然耗时较长,不过还是过了
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
print(root)
if root != None:
ans = [[root]]
else:
return []
while 1:
nodes = []
for i in ans[-1]:
if i.left != None:
nodes.append(i.left)
if i.right != None:
nodes.append(i.right)
if len(nodes) == 0:
break
else:
ans.append(nodes)
return [[x.val for x in y] for y in ans]
看看解答的思路,使用队列,神奇!自己试试!
队列好实现,但是怎么判断一层结束了呢?想过while循环里面一层一层操作,感觉这样像是暴力遍历??但是看了解答就是这样写的,为什么会耗时锐减,快了近20倍?
from collections import deque
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
que = deque()
ans = []
if root != None:
que.append(root)
else:
return []
temp = []
while len(que) != 0:
size = len(que)
temp = []
for i in range(size):
node = que.popleft()
temp.append(node.val)
if node.left: que.append(node.left)
if node.right: que.append(node.right)
ans.append(temp)
return ans
之前的遍历法是用的数组先存节点顺序,再从节点取值,如果直接取值应该会快一些,但是缩短耗时最主要的应该还是改用了deque,比列表的append操作快
多提交了几次,发现力扣这个耗时简直离谱,多提交几次就显著减少了,不能信
再做几道层序遍历题
107 二叉树的层序遍历Ⅱ
from collections import deque
class Solution:
def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
que = deque()
if root != None:
que.append(root)
else:
return []
ans = []
while len(que) != 0:
size = len(que)
temp = []
for i in range(size):
node = que.popleft()
temp.append(node.val)
if node.left != None: que.append(node.left)
if node.right != None: que.append(node.right)
ans.append(temp)
return ans[::-1]
- 二叉树的右视图
这题题意不太清楚啊,右侧包不包括右子树上的左节点呢?
靠,看到没通过的算例才明白站在右侧是啥意思
这题有点复杂啊,还得考虑被挡住的节点的没被挡住的子节点
有思路了,我可以层序遍历,然后取最后一个。。
return [x[-1] for x in ans]
637 二叉树的层平均值
return [mean(x) for x in ans]
429 N 叉树的层序遍历
if len(node.children) != 0:
for i in node.children:
que.append(i)
515 在每个树行中找最大值
return [max(x) for x in ans]
116 填充每个节点的下一个右侧节点指针
有点变化,先存储节点顺序,然后再设定指针
from collections import deque
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
que = deque()
if root != None:
que.append(root)
else:
return root
nodes = []
while len(que) != 0:
for i in range(len(que)):
node = que.popleft()
nodes.append(node)
if node.left != None: que.append(node.left)
if node.right != None: que.append(node.right)
nodes.append('#')
for i in range(len(nodes)-1):
if nodes[i] == '#':
continue
if nodes[i+1] != '#':
nodes[i].next = nodes[i+1]
else:
nodes[i].next = None
return root
解答的思路更好一些,不用储存节点,直接在遍历时就把指针设定好,而且代码写的很简洁
from collections import deque
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
que = deque()
if root != None:
que.append(root)
else:
return root
while len(que) != 0:
prev = None
for i in range(len(que)):
node = que.popleft()
if prev:
prev.next = node
prev = node
if node.left != None: que.append(node.left)
if node.right != None: que.append(node.right)
return root
117 填充每个节点的下一个右侧节点指针 II
和上一题没有区别
不过python不能使用not 后面加变量吗??
看了解答代码可以使用啊
if not root
如果root为空,那么not root就是非空,if执行
哦我明白了,用反了
104 二叉树的最大深度
from collections import deque
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
que = deque()
if root:
que.append(root)
else:
return 0
depth = 0
while len(que) != 0:
size = len(que)
depth += 1
for i in range(size):
node = que.popleft()
if node.left != None: que.append(node.left)
if node.right != None: que.append(node.right)
return depth
111 二叉树的最小深度
debug两次过的
from collections import deque
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if root:
que = deque()
que.append(root)
else:
return 0
minDepth = 0
while len(que) != 0:
flag = 0
minDepth += 1
for i in range(len(que)):
node = que.popleft()
if node.left: que.append(node.left)
if node.right: que.append(node.right)
if node.left == None and node.right == None:
flag = 1
if flag == 1:
break
return minDepth
解答更简洁一些,无需设置判断标记,符合条件可以直接无视循环return
226 翻转二叉树
感觉可以用递归,不过还是先用队列试试
一次通过
from collections import deque
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if root:
que = deque()
que.append(root)
else:
return root
while len(que) != 0:
for i in range(len(que)):
node = que.popleft()
temp = node.left
node.left = node.right
node.right = temp
if node.left: que.append(node.left)
if node.right: que.append(node.right)
return root
看了解答,先序遍历,后序遍历也可以,但中序遍历不行
可以试试递归怎么写的
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
temp = root.left
root.left = root.right
root.right = temp
self.invertTree(root.left)
self.invertTree(root.right)
return root
要注意,python写递归,调用函数需要用self.fun,但是函数的参数是不能填self的,只有在定义函数的时候才需要写self
101 对称二叉树
这个用递归好像很好理解,尝试了下还是写不出来,我对递归的理解不够。。
用队列写出来了
from collections import deque
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root: return root
que = deque([root])
record = [[1]]
while len(que) != 0:
temp = []
for i in range(len(que)):
node = que.popleft()
if node.left:
que.append(node.left)
temp.append(node.left.val)
else:
temp.append(None)
if node.right:
que.append(node.right)
temp.append(node.right.val)
else:
temp.append(None)
record.append(temp)
return [x[::-1] for x in record] == record
但是遇到了一个小问题,就是对称还含有值相等的含义,读题不仔细没理解到。。
看了解答的递归思路,为什么感觉递归好难理解啊。。
from collections import deque
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root: return True
return self.compare(root.left,root.right)
def compare(self,left,right):
if left == None and right == None:
return True
elif left == None and right != None:
return False
elif left != None and right != None:
return False
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
难搞,头要晕了,还得再熟悉一下递归的写法
此外解答的队列写法和我有不同,直接在队列中判断,不需要层序遍历得到结果再判断
而且用栈也可以