前端就该用JS写算法 – 树 – 简单的那 30%
这里优先选择了 LeetCode 热题 HOT 100 中的树题,毕竟刷题的边际收益就是冲击需要算法的面试,所以 Hot 优先级更高。
二叉树的遍历
递归遍历
- 递归的时候前中后序都能直接处理完了
- 递归是前中后序遍历最简单也是最容易出理解的方法,不懂的画个图就好了
迭代遍历 – 双色标记法
- 使用颜色标记节点状态,新节点为白色,已经访问的节点为灰色 – 可以用数字或者其他任意标签标示
- 如果遇到的节点是白色,则标记为灰色,然后将右节点,自身,左节点一次入栈 – 中序遍历
- 如果遇到的节点是灰色的,则将节点输出
- 注意这里是用 stack 栈来存储的,所以是后进先出,所以如果是中序遍历,左 - 中 - 右 ,那么在插入栈的时候要反过来 右 - 中 - 左
按照那个男人的指示,正常我们就用递归做就好,就好像我们做非排序题排序的时候,sort 一下就好了,但是一旦面试官问到用另外的迭代方式的时候,我们再套个模板,会比记住多个迭代写法要简单,毕竟内存容量有限,而后续遍历的迭代写法确实挺坑的,能省一点内存就省一点吧
144. 二叉树的前序遍历
// 144. 二叉树的前序遍历
/** * @分析 -- 递归 */
var preorderTraversal = function (root) {
const ret = [];
const recursion = (root) => {
if (!root) return;
ret.push(root.val);
recursion(root.left);
recursion(root.right);
};
recursion(root);
return ret;
};
/** * @分析 -- 迭代 -- 双色标记法 * 1. 使用颜色标记节点状态,新节点为白色,已经访问的节点为灰色 -- 可以用数字或者其他任意标签标示 * 2. 如果遇到的节点是白色,则标记为灰色,然后将右节点,自身,左节点一次入栈 -- 中序遍历 * 3. 如果遇到的节点是灰色的,则将节点输出 * 4. 注意这里是用 stack 栈来存储的,所以是后进先出,这里是前序遍历,中 - 左 - 右 ,那么在插入栈的时候要反过来 右 - 左 - 中 */
var preorderTraversal = function (root) {
const ret = [];
const stack = [];
stack.push([root, 0]); // 0 是白色未处理的,1 是灰色处理过的
while (stack.length) {
const [root, color] = stack.pop();
if (root) {
if (color === 0) {
// 遇到白球,则插入 -- 前序
stack.push([root.right, 0]);
stack.push([root.left, 0]);
stack.push([root, 1]);
} else {
// 遇到灰球,