226.翻转二叉树 (优先掌握递归)
深度优先:前序后序
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
# 深度优先
# 前序法,后序法一样
self.invert(root)
return root
def invert(self, node: Optional[TreeNode]) -> None:
if not node:
return
node.left, node.right = node.right, node.left
if node.left:
self.invert(node.left)
if node.right:
self.invert(node.right)
广度优先:
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
# 广度优先
if not root:
return None
q = collections.deque()
q.append(root)
while q:
size = len(q)
for _ in range(size):
node = q.popleft()
node.left, node.right = node.right, node.left
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
return root
101. 对称二叉树 (优先掌握递归)
深度优先
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
# 深度优先
# 前序法,前中后序应该都行,但因为需要跟递归糅合,处理左右支时得先判断node是否存在,这与前序法一致,所以直接合并效率更高
if not root:
return True
if not root.left and not root.right:
return True
result = self.checkSymmetric(root.left, root.right)
return result
def checkSymmetric(self, node_l: Optional[TreeNode], node_r: Optional[TreeNode]) -> bool:
if not node_l and not node_r:
return True
elif not node_l and node_r:
return False
elif node_l and not node_r:
return False
else:
if node_l.val != node_r.val:
return False
outer = self.checkSymmetric(node_l.left, node_r.right)
inner = self.checkSymmetric(node_l.right, node_r.left)
result = outer and inner
return result
广度优先
层序遍历也行,node加0和判断单双数能通过,至于为啥,没懂
(懂了:首先判断上一层是否对成,在上一层对称的前提下,下一层不对成的情况是1.数量多了/少了 2.数字不对称 3.数量数字都对称的情况下,位置不对称,这些都能用levels != levels[::-1]来解决。)
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
if not root:
return True
queue = collections.deque([root.left, root.right])
while queue:
level_size = len(queue)
if level_size % 2 != 0:
return False
level_vals = []
for i in range(level_size):
node = queue.popleft()
if node:
level_vals.append(node.val)
queue.append(node.left)
queue.append(node.right)
else:
level_vals.append(None)
if level_vals != level_vals[::-1]:
return False
return True
104.二叉树的最大深度 (优先掌握递归)
广度优先--层序
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
result = 0
q = collections.deque()
q.append(root)
while q:
size = len(q)
# level = []
if size:
result += 1
for i in range(size):
node = q.popleft()
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
# result.append(level)
# for i in range(size-1):
# level[i].next = level[i+1]
return result
深度优先--后序
最大深度就等于最大高度
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
result = self.getMaxHeight(root)
return result
def getMaxHeight(self, node: Optional[TreeNode]) -> int:
# 深度遍历
# 后序遍历
if node == None:
return 0
left_max_height = self.getMaxHeight(node.left)
right_max_height = self.getMaxHeight(node.right)
max_height = 1+max(left_max_height, right_max_height)
return max_height
深度优先--前序
知道每个结点的depth,跟result来比更新result,result最后就是最大的深度
class Solution:
result = 0 # static variable
def maxDepth(self, root: Optional[TreeNode]) -> int:
Solution.result = 0
self.getDepth(root, depth=1)
return Solution.result
def getDepth(self, node: Optional[TreeNode], depth: int) -> None:
# 深度优先
# 前序遍历
if node == None:
return
# 中
if depth > Solution.result:
Solution.result = depth
# 左
if node.left:
depth += 1
self.getDepth(node.left, depth)
depth -= 1
# 右
if node.right:
depth += 1 # 向下遍历增加
self.getDepth(node.right, depth)
depth -= 1 # 返回回归原值
return
111.二叉树的最小深度 (优先掌握递归)
层序法
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
result = 0
q = collections.deque()
q.append(root)
while q:
size = len(q)
# level = []
if size:
result += 1
for i in range(size):
node = q.popleft()
if not node.left and not node.right:
return result
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
# result.append(level)
# for i in range(size-1):
# level[i].next = level[i+1]
return result
深度优先:
找到叶子结点,再求depth/height
后序法:
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
# 后序法
# 找到一个最小的叶子结点
result = self.getHeight(root)
return result
def getHeight(self, node: Optional[TreeNode]) -> int:
if not node:
return 0
leftHeight = self.getHeight(node.left)
rightHeight = self.getHeight(node.right)
# 找到一个叶子结点,求height
if not node.left and not node.right:
height = 1
if not node.left and node.right:
height = 1 + rightHeight
if node.left and not node.right:
height = 1 + leftHeight
if node.left and node.right:
height = 1 + min(leftHeight, rightHeight)
return height
前序法:
class Solution:
result = 0
def minDepth(self, root: Optional[TreeNode]) -> int:
# 前序法
# 找到一个最小的叶子结点
if not root:
return 0
Solution.result = 10**5
self.getDepth(root, depth=1)
return Solution.result
def getDepth(self, node: Optional[TreeNode], depth: int):
if not node:
return
# 找到一个叶子结点(node有值,left,right都没值),更新result
if not node.left and not node.right:
if depth<Solution.result:
Solution.result = depth
self.getDepth(node.left, depth+1)
self.getDepth(node.right, depth+1)