LeetCode 226. 翻转二叉树

leetcode.cn/problems/in...

programmercarl.com/0226.%E7%BF...

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:

ini 复制代码
输入: root = [4,2,7,1,3,6,9]
输出: [4,7,2,9,6,3,1]

示例 2:

ini 复制代码
输入: root = [2,1,3]
输出: [2,3,1]

示例 3:

ini 复制代码
输入: root = []
输出: []

提示:

  • 树中节点数目范围在 [0, 100] 内
  • -100 <= Node.val <= 100

如果要从整个树来看,翻转还真的挺复杂,整个树以中间分割线进行翻转,如图:

可以发现想要翻转它,其实就把每一个节点的左右孩子交换一下就可以了。

遍历的过程中去翻转每一个节点的左右孩子就可以达到整体翻转的效果。

注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果

这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次!建议拿纸画一画,就理解了

那么层序遍历可以不可以呢?依然可以的!只要把每一个节点的左右孩子翻转一下的遍历方式都是可以的!

递归法

我们下文以前序遍历为例,通过动画来看一下翻转的过程:

我们来看一下递归三部曲:

  1. 确定递归函数的参数和返回值

参数就是要传入节点的指针,不需要其他参数了,通常此时定下来主要参数,如果在写递归的逻辑中发现还需要其他参数的时候,随时补充。

返回值的话其实也不需要,但是题目中给出的要返回root节点的指针,可以直接使用题目定义好的函数,所以就函数的返回类型为TreeNode*。

java 复制代码
TreeNode* invertTree(TreeNode* root)
  1. 确定终止条件

当前节点为空的时候,就返回

java 复制代码
if (root == NULL) return root;
  1. 确定单层递归的逻辑

因为是前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。

java 复制代码
swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);

基于这递归三步法,代码基本写完,C++代码如下:

java 复制代码
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return root;
        swap(root->left, root->right);  // 中
        invertTree(root->left);         // 左
        invertTree(root->right);        // 右
        return root;
    }
};

kotlin 代码如下:

kotlin 复制代码
class Solution {
    fun invertTree(root: TreeNode?): TreeNode? {
        if (root == null) return root
        val temp = root.left
        root.left = root.right
        root.right = temp
        invertTree(root.left)
        invertTree(root.right)
        return root
    }
}

深度优先遍历

基于前序遍历,kotlin 代码:

kotlin 复制代码
class Solution {
    fun invertTree(root: TreeNode?): TreeNode? {
        val stack = Stack<TreeNode>()
        stack.push(root)
        while (stack.isNotEmpty()) {
            val top = stack.pop()
            if (top != null) {
                val temp = top.left
                top.left = top.right
                top.right = temp
                if (top.right != null) {
                    stack.push(top.right)
                }
                if (top.left != null) {
                    stack.push(top.left)
                }
            }
        }
        return root
    }
}

广度优先遍历

也就是层序遍历,层数遍历也是可以翻转这棵树的,因为层序遍历也可以把每个节点的左右孩子都翻转一遍,代码如下:

java 复制代码
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                swap(node->left, node->right); // 节点处理
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return root;
    }
};

kotlin 代码:

kotlin 复制代码
class Solution {
    fun invertTree(root: TreeNode?): TreeNode? {
        if (root == null) return root
        val queue = Stack<TreeNode>()
        queue.push(root)
        while (queue.isNotEmpty()) {
            val size = queue.size
            for (i in 0..<size) {
                val cur = queue.pop()
                val temp = cur.left
                cur.left = cur.right
                cur.right = temp
                if (cur.left != null) {
                    queue.push(cur.left)
                }
                if (cur.right != null) {
                    queue.push(cur.right)
                }
            }
        }
        return root
    }
}
相关推荐
朝朝辞暮i1 小时前
C++ 第 31C 课:Subscriber 到底是什么
开发语言·c++·算法
Evand J2 小时前
【MATLAB例程】三维RRT+APF路径规划与AOA-TDOA融合定位算法。附代码的下载链接
算法·matlab·路径规划·rrt·tdoa·apf·aoa
海绵宝宝转agent2 小时前
leetCode100算法开源笔记分享
笔记·算法
写后端的胖头鱼3 小时前
时间复杂度 & 空间复杂度
java·数据结构·算法·时间复杂度·空间复杂度
hahaha60163 小时前
黑体轨迹和色温--光源白点
人工智能·嵌入式硬件·算法·计算机视觉
海绵宝宝转agent3 小时前
基于Redis ZSet+AOP+注解实现限流注解算法
数据库·redis·算法
All for pursuit.4 小时前
【回溯-7】494.目标和
数据结构·c++·算法·leetcode
白杨尚青4 小时前
C++入门篇(十三):vector(上)——动态数组:构造、空间增长与迭代器失效
开发语言·c++·笔记·算法·stl
Jasmine_llq4 小时前
《P17461 [GESP202609 八级] 生成树计数》
算法·栈·tarjan 算法·边双连通分量·深度优先搜索 dfs·tarjan 保存当前路径节点·模乘法
Jasmine_llq4 小时前
《P17462 [GESP202609 八级] 末班车》
算法·dijkstra 算法·最大化版本,求最长可行值·建反向图(逆图 / 反转边)·多源 dijkstra 思想·对每个终点单独跑一遍djst·离线预处理 + 在线查询