「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」。
题目
给你二叉树的根结点 root ,请你将它展开为一个单链表:
- 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
- 展开后的单链表应该与二叉树 先序遍历 顺序相同。
示例1
输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]
示例2
输入:root = []
输出:[]
示例3
输入:root = [0]
输出:[0]
思路
从题意可知,单链表的顺序,是二叉树按照 前序遍历 的得到的结果;那么先用 前序遍历,将每个节点放入一个数组 stack 中,这样就会得到如下的结果
[节点1, 节点2, 节点3, ...., 最后的节点]
然后会发现,如果遍历这个数组,将节点1的左节点指向 null,将节点1的右节点指向节点二,重复这个步骤,直到遍历完成,原有的二叉树,就会变成符合题意的链表。
不熟悉二叉树前、中、后序遍历的,可以先看这篇 二叉树的中、先、后序遍历
完整代码如下
/**
* 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 {void} Do not return anything, modify root in-place instead.
*/
var flatten = function(root) {
const stack = [];
// 前序遍历
const traver = node => {
if(!node) return;
stack.push(node);
traver(node.left);
traver(node.right);
}
traver(root);
// 遍历每个节点
for(let i = 1; i < stack.length; i++) {
const prev = stack[i - 1], cur = stack[i];
prev.right = cur;
prev.left = null;
}
};
思考: 做些优化,在遍历二叉树的过程中,可以这么做,如果当前节点存在右节点,将右节点放入 stack 中,将左节点放在右节点上,继续遍历这个左节点,重复上述过程,每次遍历时更新当前节点为 lasrNode 最后一个节点,定义上述过程为一个函数 dfs(root);这样遍历完成后,会得到:
二叉树的左节点都放在右节点上了
一个保存了所有右节点的 stack
一个 lastNode 指向二叉树的最后一个节点
这时候从 stack 取出最后一个节点 node,放在 lastNode 的右节点上,同时对 node 使用上述函数 dfs,当 stack 不为空时,重复上述算法;
优化后代码
/**
* @param {TreeNode} root
* @return {void} Do not return anything, modify root in-place instead.
*/
var flatten = function(root) {
const stack = [];
let lastNode = root
const dfs = node => {
if(!node) return;
lastNode = node;
if(node.right) stack.push(node.right);
node.right = node.left;
dfs(node.left)
node.left = null;
}
dfs(root);
// stack 不为空时 取出最后一个节点
while(stack.length) {
let currentNode = stack.pop();
lastNode.right = currentNode;
dfs(lastNode.right);
lastNode.left = null;
}
小结
二叉树的遍历,熟能生巧~
LeetCode 👉 HOT 100 👉 二叉树展开为链表 - 中等题 ✅
合集:LeetCode 👉 HOT 100,有空就会更新,大家多多支持,点个赞👍
如果大家有好的解法,或者发现本文理解不对的地方,欢迎留言评论 😄