114. 二叉树展开为链表 --- 头插法(js)
114.二叉树展开为链表 — 头插法(js)
- 题目描述
- 关键思路
- 完整代码
题目描述
114. 二叉树展开为链表
关键思路
-
为什么要用头插法?
遍历顺序是:右 → 左 → 根
插入顺序就变成:根 → 左 → 右,正好是 先序遍历的顺序。
优点:
- 原地修改,不需要辅助栈
- 空间复杂度 O(1)
-
整体上是一个 dfs
-
按照 右-左-根 的顺序遍历树节点
-
根据题目要求,左子树指向 null, 右子树指向下一个节点(可以理解为上一个已经处理好的链表头)
-
然后把新的头节点设置为当前遍历到的根节点
用这个例子描述一下过程:
从最右侧开始拼接链表,处理顺序如下:
node (当前处理节点) | head(已经构建好的链表的头节点) | 操作 |
---|---|---|
6 | null | 6.right = null, head = 6 |
5 | 6 | 5.right = 6, head = 5 |
4 | 5 | 4.right = 5, head = 4 |
3 | 4 | 3.right = 4, head = 3 |
2 | 3 | 2.right = 3, head = 2 |
1 | 2 | 1.right = 2, head = 1 |
完整代码
var flatten = function(root) {let head = null;function dfs(node) {if (!node) return;dfs(node.right); // 先处理右子树dfs(node.left); // 再处理左子树node.left = null; node.right = head; // 当前节点的右指针指向已经处理好的链表头(也就是上一个节点)head = node; // 现在链表头节点是 node}dfs(root);
};