226. 翻转二叉树|刷题打卡

408 阅读3分钟

226. 翻转二叉树|刷题打卡

create by db on 2021-3-5 23:22:17
Recently revised in 2021-3-5 23:32:22

闲时要有吃紧的心思,忙时要有悠闲的趣味

原题链接226. 翻转二叉树

目录

题目描述

返回目录

翻转一棵二叉树。

示例:

输入:

     4
   /   \
  2     7
 / \   / \
1   3 6   9
输出:

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

备注:

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

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

思路分析

 这也是一道简单题,不过对我们这些算法小白来说是个认识这一数据结构的不错选择。

 那什么是树结构呢?

树(Tree)的基本概念

 树是由结点或顶点和边组成的(可能是非线性的)且不存在着任何环的一种数据结构。没有结点的树称为空(null 或 empty)树。一棵非空的树包括一个根结点,还(很可能)有多个附加结点,所有结点构成一个多级分层结构。

二叉树

 每个结点至多拥有两棵子树(即二叉树中不存在度大于 2 的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。

二叉树的性质

  1. 若二叉树的层次从 0 开始,则在二叉树的第 i 层至多有 2^i 个结点(i>=0)
  2. 高度为 k 的二叉树最多有 2^(k+1) - 1 个结点(k>=-1)(空树的高度为-1)
  3. 对任何一棵二叉树,如果其叶子结点(度为 0)数为 m, 度为 2 的结点数为 n, 则 m = n + 1

思路一:递归

 这是一道很经典的二叉树问题。我们就使用最经典的解法——递归。

 从根节点开始,交换当前左右子节点,并且递归地对左右子树进行交换左右子节点操作,最会返回交换后的树即可。

思路二:

 我们也可以用栈来做。

  1. 根节点先入栈,然后出栈,出栈就 “做事”,交换它的左右子节点(左右子树)。

  2. 让左右子节点入栈,往后,这些子节点出栈,也被翻转。

  3. 直到栈为空,就遍历完所有的节点,翻转了所有子树。

AC 代码

题解一:递归

/**
 * 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) {
  // 非空判断,也是终止调教
  if (!root) {
    return root
  }
  // 交换左右子节点
  let temp = root.left
  root.left = root.right
  root.right = temp

  // 递归调用,嗅探下一层,交换左右子节点
  invertTree(root.left)
  invertTree(root.right)

  // 返回当前树
  return root
}

解构赋值版:

var invertTree = function (root) {
  if (root) {
    ;[root.left, root.right] = [invertTree(root.right), invertTree(root.left)]
  }
  return root
}

题解二:正反查找

/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var invertTree = function(root) {
  if (!root) {
    return null
  }
  // 声明数组来模拟栈
  const queue = []
  // 根节点先入栈
  queue.push(root)
  while(queue.length) {
    // 根节点出栈
    const top = queue.shift()
    // 交换子节点
    const _left = top.left
    const _right = top.right
    top.right = _left
    top.left = _right
    // 左右子节点入栈
    if (top.left) {
      queue.push(top.left)
    }
    if (top.right) {
      queue.push(top.right)
    }
  }
  return root
};

总结

返回目录

 很简单的一道题,柿子先挑软的捏……

 三月你好,春暖花开。加油!

 本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情

后记:Hello 小伙伴们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富文章的动力!GitHub 地址

文档协议

知识共享许可协议
db 的文档库db 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/danygitgit上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。