大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。
题目
226. 翻转二叉树
翻转一棵二叉树。
示例:
输入:
4
/ \
2 7
/ \ / \
1 3 6 9
复制代码
输出:
4
/ \
7 2
/ \ / \
9 6 3 1
复制代码
备注:
这个问题是受到 Max Howell 的 原问题 启发的 :
谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。
思路
- 这道题目之前咱们用递归法解过一次了, 如果还没看过的小伙伴可以先看一下我这篇文章[路飞]_送给前端开发者的二叉树入门教程;
- 今天主要分享一下如何用迭代法来做二叉树的题目,正常来讲用递归解二叉树是最快的,但是递归太深容易带来栈溢出的副作用,比如说我们有一个Map对象,迭代法只需要在函数中定义一次,就可以一直用了,而递归法需要一直把它作为参数一层层传递下去;
- 迭代的本质是找到当前一轮转换成下一轮的秘诀,比如说树的迭代,可以由当前层转向下一层,层层递进;
- 那么我们只需要用把下一轮的有效节点收集起来,当前轮执行完之后把下一轮的值作为当前值迭代执行即可。
实现
/**
* 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) {
// 这道题用栈和队列没所谓的,一个是dfs一个是bfs
let queue = [ root ];
// 如果还有下一轮的话
while (queue.length) {
// 执行当前轮,执行完后把下一轮的有效节点作为当前值进行下一轮循环
queue = queue.reduce((total, cur) => {
if (!cur) return total;
// 交换左右节点的位置
[ cur.right, cur.left ] = [ cur.left, cur.right ]
// 记录下一轮的有效节点
cur.left && total.push(cur.left);
cur.right && total.push(cur.right);
return total;
}, []);
}
return root;
};
复制代码
看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。