[路飞]算法:翻转二叉树

97 阅读1分钟

226. 翻转二叉树

正题

翻转一棵二叉树。

示例:

输入:

    4
   /   \
  2     7
 / \   / \
1   3 6   9

输出:

     4
   /   \
  7     2
 / \   / \
9   6 3   1

这个问题是受到 Max Howell 的 原问题 启发的。

image.png

谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。

解析

既然 90% 的工程师不能再面试中写出翻转二叉树,那我们一定要努力成为超越那90%的 developer!

划重点:二叉树的翻转实际上就是将二叉树的每一个节点的 子节点左右交换

我们未必会用到递归,但一定是要会遍历二叉树的。几乎99%的二叉树问题都会涉及到二叉树的遍历。

既然是“每个节点的子节点交换”,那么我们肯定需要遍历到每一个节点,所以首先实现的是二叉树的遍历。

以测试用例

     4
   /   \
  2     7
 / \   / \
1   3 6   9

为例

前序遍历翻转二叉树

var invertTree = function (root) {
    const stack = root ? [root] : []
    while(stack.length) {
        const node = stack.pop()
        node.left ? stack.push(node.left) : ''
        node.right ? stack.push(node.right) : ''
        console.log(node.val)
    }
}

运行结果: 4 7 9 6 2 3 1

第二步即是在遍历出来的 node 中,交换他们的子节点

子节点的交换

const node = stack.pop()
const tempNode = node.left
node.left = node.right
node.right = tempNode

完整代码:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var invertTree = function(root) {
    const stack = root ? [root] : []
    while(stack.length) {
        // 前序遍历
        const node = stack.pop()
        // 节点交换
        const tempNode = node.left
        node.left = node.right
        node.right = tempNode
        node.left ? stack.push(node.left) :''
        node.right ? stack.push(node.right): ''
    }
    // 返回根节点
    return root
};

image.png

在 leetcode 上归属于简单题,实际上并不难,抓住交换子节点这个核心,配合二叉树的遍历就可以实现了。