226. 翻转二叉树
简单
给你一棵二叉树的根节点 root
,翻转这棵二叉树,并返回其根节点。
方法一:递归(前/后)
递归三部曲:
- 传入参数和返回值:无需参数、返回根节点root
- 终止条件:当前节点为空的时候,就返回
if root == NULL: return root
- 确定单层递归的逻辑:
前序遍历,先交换左右孩子节点,然后反转左子树,反转右子树。若是后序遍历(左右中),交换顺序即可。
# 前序遍历 root.left, root.right = root.right, root.left #中 self.invertTree(root.left) #左 self.invertTree(root.right)#右 # 后序遍历 self.invertTree(root.left) #左 self.invertTree(root.right)#右 root.left, root.right = root.right, root.left #中
不可以中序遍历的原因:会重复处理左子树
解决方法:
单层代码逻辑里,左中后再次左
self.invertTree(root.left) # 左 root.left, root.right = root.right, root.left # 中 self.invertTree(root.left) # 左
前序遍历
# 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: TreeNode) -> TreeNode:
if not root:
return None
root.left, root.right = root.right, root.left
self.invertTree(root.left)
self.invertTree(root.right)
return root
后序遍历
# 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: TreeNode) -> TreeNode:
if not root:
return None
self.invertTree(root.left)
self.invertTree(root.right)
root.left, root.right = root.right, root.left
return root
中序遍历
# 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: TreeNode) -> TreeNode:
if not root:
return None
self.invertTree(root.left)
root.left, root.right = root.right, root.left
self.invertTree(root.left)
return root
方法二:迭代
深度优先遍历(前中后):栈
广度优先遍历(层序遍历):队列
前序遍历
# 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: TreeNode) -> TreeNode:
if not root:
return None
stack = [root]
while stack:
node = stack.pop()
node.left, node.right = node.right, node.left
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return root
后序遍历
# 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: TreeNode) -> TreeNode:
if not root:
return None
stack = [root]
while stack:
node = stack.pop()
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
node.left, node.right = node.right, node.left
return root
中序遍历
# 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: TreeNode) -> TreeNode:
if not root:
return None
stack = [root]
while stack:
node = stack.pop()
if node.left:
stack.append(node.left)
node.left, node.right = node.right, node.left
if node.left:
stack.append(node.left)
return root
层序遍历
# 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: TreeNode) -> TreeNode:
if not root:
return None
queue = collections.deque([root])
while queue:
for i in range(len(queue)):
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. 对称二叉树
简单
给你一个二叉树的根节点 root
, 检查它是否轴对称。
方法一:递归(后序)
注意点1:比较的是什么,要比较的可不是左右节点!
其实要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。
比较的是两个子树的里侧和外侧的元素是否相等
注意点2:遍历顺序
要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。
所以只能后序遍历
注意点3:判断空节点 若p和q有至少一个节点为空,判断p is q
- p、q 其中有一个是none,判断p、q是否为同一对象
- p、q都为空,p is q为true
则接下来的情况为p、q都不为空
# 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 isSame(self, p:Optional[TreeNode], q:Optional[TreeNode])->bool:
if p is None or q is None:
return p is q
return p.val == q.val and self.isSame(p.left,q.right) and self.isSame(q.left,p.right)
def isSymmetric(self,root:Optional[TreeNode]):
return self.isSame(root.left,root.right)
方法二:迭代(层序)
使用队列,加入一层的节点,层序遍历,每次弹出两个节点进行比较(按照代码顺序是先外侧后内侧)
比较逻辑:
- 若都为空,continue跳出迭代,继续比较另外两个节点
- 一个为空一个不为空:false
- 都不为空,但值不相同:false
使用栈也可以
# 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 True
queue = deque()
queue.append(root.left)
queue.append(root.right)
while queue:
leftnode = queue.popleft()
rightnode = queue.popleft()
# if not leftnode or not rightnode:
# return leftnode is rightnode
# 这样判断当有一个为空时逻辑正确,但都为空时就直接返回true,应该继续比较
if not leftnode and not rightnode:
continue
# 只有一个为空,不对称
if not leftnode or not rightnode:
return False
# 值不相等,不对称
if leftnode.val != rightnode.val:
return False
queue.append(leftnode.left)
queue.append(rightnode.right)
queue.append(leftnode.right)
queue.append(rightnode.left)
return True
104. 二叉树的最大深度
简单
给定一个二叉树 root
,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
方法一:递归(后序求高度)
根节点的高度就是二叉树的最大深度,通过后序求的根节点高度来求的二叉树最大深度。
高度:从下往上----后序遍历
深度:从上往下----前序遍历
递归三部曲:
- 确定参数和返回值:参数为要传入的二叉树根节点,返回的是int类型的深度。
- 终止条件:if not root: return 0 表示当前节点的高度为0
- 单层递归的逻辑:后序求高度 左右中
# 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 maxDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
l_depth= self.maxDepth(root.left) # 左
r_depth = self.maxDepth(root.right) # 右
height = max(l_depth,r_depth) +1 # 中
return height
方法二:迭代(层序-队列)
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
q = deque([root])
ans = 0
while q:
for _ in range(len(q)): #如果没有这句每次只让当层的一个节点出队,进行下一个循环,ans值偏高。
node = q.popleft()
if node.left: q.append(node.left)
if node.right: q.append(node.right)
ans+=1
return ans
111. 二叉树的最小深度
简单
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
方法一:递归(后序)
递归三部曲:
- 确定参数和返回值:参数为要传入的二叉树根节点,返回的是int类型的深度。
- 终止条件:if not root: return 0 表示当前节点的高度为0
- 单层递归的逻辑:后序求高度 左右中
仿照最大深度可以写出如下代码:
leftDepth = self.getDepth(node.left) # 左 rightDepth = self.getDepth(node.right) # 右 result = 1 + min(leftDepth, rightDepth) #中
错误的原因:左右孩子都为空的节点才是叶子节点!如果这么求的话,没有左孩子的分支会算为最短深度。
修改:增加判断
- 如果左子树为空,返回右子树最小高度+1
- 如果右子树为空,返回左子树最小高度+1
- 如果左右都不空,返回左右子树深度最小值 + 1 。
# 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
if root is None:
return 0
if root.left is None:
return self.minDepth(root.right)+1
if root.right is None:
return self.minDepth(root.left)+1
l_depth = self.minDepth(root.left)
r_depth = self.minDepth(root.right)
return min(l_depth,r_depth)+1
# return min(l_depth,r_depth)+1 if min(l_depth,r_depth)+1!=1 else max(l_depth,r_depth)+1
方法二:迭代 (层序)
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
q = deque([root])
ans = 1
while q:
for _ in range(len(q)):
node = q.popleft()
if node.left is None and node.right is None:
return ans
if node.left: q.append(node.left)
if node.right: q.append(node.right)
ans+=1