2025/09/02 二叉树6.翻转二叉树
方法1: 迭代法,广度优先遍历(层序遍历)
class Solution: def invertTree(self, root: TreeNode) -> TreeNode: if not root: return None queue = collections.deque([root]) while 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
方法2-1:递归法,前序遍历
class Solution: def invertTree(self, root: TreeNode): if not root: return None root.left, root.right = root.right, root.left self.invertTree(root.left) self.invertTree(root.right) return root
方法2-2:迭代法,前序遍历
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.right: stack.append(node.right) if node.left: stack.append(node.left) return root
方法3-1:递归法:中序遍历
这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次。
递归的中序遍历是不行的,因为使用递归的中序遍历,某些节点的左右孩子会翻转两次。
如果非要使用递归中序的方式写,也可以,如下代码就可以避免节点左右孩子翻转两次的情况:
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): if not root: return None self.invertTree(root.left) root.left, root.right = root.right, root.left self.invertTree(root.left) # 注意,这里处理的仍然是left return root
代码虽然可以,但这毕竟不是真正的递归中序遍历了。
但使用迭代方式统一写法的中序是可以的。这是用栈来遍历,而不是靠指针来遍历,避免了递归法中翻转了两次的情况。
方法3-2:迭代法,伪中序遍历(结果是对的,看起来像是中序遍历,实际上它是前序遍历,只不过把中间节点处理逻辑放到了中间。还是要用'统一写法'才是真正的中序遍历):
class Solution: def invertTree(self, root: TreeNode) -> TreeNode: if not root: return None stack = [root] while stack: node = stack.pop() if node.right: stack.append(node.right) node.left, node.right = node.right, node.left # 放到中间,依然是前序遍历 if node.right: stack.append(node.right) # 注意这里处理的仍然是right return root
方法3-3:迭代法,中序遍历统一写法-空指针标记法
class Solution: def invertTree(self, root: TreeNode) -> TreeNode: if not root: return None st = [root] while st: node = st.pop() if node != None: if node.right: st.append(node.right) st.append(node) st.append(None) if node.left: st.append(node.left) else: node = st.pop() node.left, node.right = node.right, node.left return root
方法3-4:迭代法,中序遍历统一写法-boolean标记法
class Solution: def invertTree(self, root: TreeNode) -> TreeNode: st = [(root, False)] if root else [] while st: node, visited = st.pop() if visited: node.left, node.right = node.right, node.left continue if node.right: st.append((node.right, False)) st.append((node, True)) if node.left: st.append((node.left, False)) return root
方法4-1:递归法,后序遍历
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
方法4-2:迭代法,伪后序遍历(结果是对的,看起来像是后序遍历,实际上它是前序遍历,只不过把中间节点处理逻辑放到了最后。还是要用'统一写法'才是真正的后序遍历):
class Solution: def invertTree(self, root: TreeNode) -> TreeNode: if not root: return None st = [root] while st: node = st.pop() if node.right: st.append(node.right) if node.left: st.append(node.left) node.left, node.right = node.right, node.left # 放到最后,依然是前序遍历 return root
方法4-3:迭代法,后序遍历统一写法-空指针标记法
class Solution: def invertTree(self, root: TreeNode) -> TreeNode: if not root: return None st = [root] while st: node = st.pop() if node != None: st.append(node) st.append(None) if node.right: st.append(node.right) if node.left: st.append(node.left) else: node = st.pop() node.left, node.right = node.right, node.left return root