1. 问题描述
LeetCode第226题,题目名称为二叉树翻转
triv·i·a : details, considerations, or pieces of information of little importance or value. 翻译为细节,无用的细节
2. 思考
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def invertTree(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
2.1 这类传入一个root的,首先要判断root是否是None
2.2 翻转根节点为root的二叉树,将问题分解为翻转根节点为root.left的二叉树,翻转根节点为root.right的二叉树,交换root节点左右子树。
翻转根节点为root的二叉树 = 翻转根节点为root.left的二叉树 (问题的自相似性,使用递归 recursive 解决)
+ 翻转根节点为root.right的二叉树 (问题的自相似性,使用递归解决)
+ 交换root节点左右子树
2.3 思考递归结束条件
一个根节点左右子树都不存在,翻转该节点没有意义,直接返回该节点就可以了
或者
这个根节点本身就不存在(这就是2.1 描述的情况),直接返回None就可以了
3. 问题解决方案
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution(object): def invertTree(self, root): """ :type root: TreeNode :rtype: TreeNode """ if not root: return None if root.left or root.right: root.left, root.right = self.invertTree(root.right), self.invertTree(root.left) return root
3.1 重构代码
def invertTree(self, root):
#就假设root存在,如果不存在 该段代码默认返回None
if root:
root.left, root.right = self.invertTree(root.right), self.invertTree(root.left)
return root
3.2 自己建一个stack,模拟系统维护的call stack,
这其实就是DFS,这个DFS的顺序是从树的右子树进行不停的深入,但是由于树的左右子树交换了位置,所以在可视化里面看起来像一直从树的左子树不停的深入
# DFS
def invertTree(self, root):
#stack初始化
stack = [root]
while stack:
#循环做如下动作:pop会删除list末尾的元素,做操作,新的元素也加在list末尾
node = stack.pop()
if node:
node.left, node.right = node.right, node.left
stack += node.left, node.right #向stack中加入待处理节点
return root
3.3 自己建一个queue,
可以实现BFS,先append 左子树,再append右子树,所以整个遍历过程是从左到右一层一层的遍历的
# BFS
def invertTree2(self, root):
queue = collections.deque([(root)])
while queue:
node = queue.popleft()
if node:
node.left, node.right = node.right, node.left
queue.append(node.left) #向queue中加入待处理节点
queue.append(node.right)
return root
4. 代码可视化
4.1 DFS
4 / \ 2 7 stack = [4] stack中存储需要翻转的节点 / \ / \ 1 3 6 9
--------->
4 / \ 7 2 stack = [2, 7] / \ / \ 6 9 1 3
--------->
4 / \ 7 2 stack = [2, 6, 9] / \ / \ 9 6 1 3
这样的结构准确描述翻转的过程,后面就不详细画了
5. 参考链接
3中的重构代码,自己建一个stack均来自于LeetCode Discuss
3中的BFS方法来自于LeetCode Discuss