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