Q1.翻转二叉树(easy)

如题所示

示例:

输入:

     4
/ \
2 7
/ \ / \
1 3 6 9 输出: 4
/ \
7 2
/ \ / \
9 6 3 1 来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/invert-binary-tree

这道题目起源于一个非常搞笑的事件:据说大名鼎鼎的Mac软件包管理工具Homebrew的作者,因为做不出这道在leetcode上难度为easy的题,被谷歌公司拒了。。。

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

如何看待 Max Howell 被 Google 拒绝?​www.zhihu.com

格式要求

/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
var invertTree = function(root) {
// 编码
};

分析:二叉树遍历

思路就是遍历二叉树的每一个节点,然后把左右链接替换一下就可以了。前序/中序/后序 都可以。如下所示

具体代码

var invertTree = function(root) {
traveral(root);
return root;
}; function traveral(node) {
if (node === null) return;
traveral(node.left);
traveral(node.right);
const temp = node.right;
node.right = node.left;
node.left = temp;
}

Q2.二叉树的右视图(middle)

给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

输入: [1,2,3,null,5,null,4]
输出: [1, 3, 4]
解释: 1 <---
/ \
2 3 <---
\ \
5 4 <--- 输入: [1,2,3,null,5,null,null]
输出: [1, 3, 5]
解释:
1 <---
/ \
2 3 <---
\
5 <--- 来源:LeetCode
链接:https://leetcode-cn.com/problems/binary-tree-right-side-view

格式要求

/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/ /**
* @param {TreeNode} root
* @return {number[]}
*/
var rightSideView = function(root) {
// 编码
}

分析:层序遍历

题目的思路很明显,对二叉树进行层序遍历,然后取得每一层的最后一个节点。放到一个数组里最后返回。

1.我们可以设置一个队列存放依次遍历的节点对象。

2.使用两层循环

  • 内层循环通过不断出队列的方式遍历当前层的节点,同时通过左右链接收集下一层节点

  • 外层循环判断队列长度>0时就继续运行,从而实现逐层迭代

3.在每次内层循环中获取最右端的非空节点

具体代码

var rightSideView = function(root) {
if (!root) return [];
const queue = [];
const arrRS = [];
// 先保存根结点,也就是第一层二叉树
queue.push(root);
while (queue.length > 0) {
// 将队列长度先保存到一个变量里面
// 表示的是上一层的节点的数量
let length = queue.length;
let temp = null;
// 遍历上一层节点,将它们的子节点加入队列中,收集得到二叉树的下一层
for (let i = 0; i < length; i++) {
// 出队列,并获得返回的父节点
const node = queue.shift();
// 每次都用当前节点的val覆盖temp
// temp最后会等于当前层最右的一个非空节点的val值
if (node.val) temp = node.val;
// 收集当前节点的左节点和右节点,从而得到下一层
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
// 收集每一层的最右节点
arrRS.push(temp);
}
return arrRS;
};

Q3.二叉树中的最大路径和(difficult)

给定一个非空二叉树,返回其最大路径和。

本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。

示例1:
输入: [1,2,3] 1
/ \
2 3 输出: 6 示例2:
输入: [-10,9,20,null,null,15,7] -10
/ \
9 20
/ \
15 7 输出: 42 来源:LeetCode
链接:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/

格式要求

/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var maxPathSum = function(root) {
// 编码
};

思路分析

1.整体思路:通过后序遍历,自底向上计算。

因为后序遍历的计算过程是:左节点-右节点-根结点。 所以通过这种遍历方式,我们可以在计算两个子节点的基础上,推断当这两个节点到父节点的最大路径和。然后不断向上累加,去计算最大值。

同时在每个节点都通过Math.max更新当前的最大值,直到回归到根结点的时候,也就能比较出最大值来了。

2.路径的单一性: 当一个节点是只是作为一个中间节点,而不是一个根节点的时候:左节点和右节点只能选择一个作为经过的路径。 因为路径是“单一”的而不是“分叉”的

例如下面的图示中, 当我们通过比较选择9-7-10这条的时候,节点8就不在路径内了

3.根节点的连接性:当一个节点作为根节点的时候,它可以将两个子树的路径连接起来

4. 对于两个子节点的累加值A,B,分3种情况讨论

  • A>0,B>0: 选择Math.max(A,B)作为经过路径

  • A>0,B<0: 选择A作为经过路径

  • A<0,B>0: 选择B作为经过路径

  • A<0,B<0: A,B都不选

综上所述

我们的思路是:

  1. 后序遍历,自底向上计算

  2. 对于每个节点,假设它是根结点,计算它联合两个子树路径后的最大值

  3. 对于每个节点,假设它是中间节点,选择两条中较大的一条子树作为路径

  4. 对于2,3分上面的四种情况进行分别处理

具体代码

// 1.考虑全为负数的情况
// 2.考虑当前节点为负的情况
let max = Number.MIN_VALUE;
var maxPathSum = function(root) {
max = root.val;
traveral(root);
return max;
}; function traveral(node) {
if (node === null) return 0;
const a = traveral(node.left);
const b = traveral(node.right);
let v = node.val;
if (a >= 0 && b >= 0) {
max = Math.max(max, v + a + b);
v += Math.max(a, b);
} else if (a >= 0) {
max = Math.max(max, v + a);
v += a;
} else if (b >= 0) {
max = Math.max(max, v + b);
v += b;
}
return v;
} function TreeNode(val) {
this.val = val;
this.left = this.right = null;
}
 

本文完

JS刷算法题:二叉树的更多相关文章

  1. 19道常见的JS面试算法题

    最近秋招也做了多多少少的面试题,发现除了基础知识外,算法还是挺重要的.特意整理了一些常见的算法题,添加了自己的理解并实现. 除此之外,建议大家还可以刷刷<剑指offer>.此外,左神在牛客 ...

  2. js的算法题

    1.统计一个字符串中出现最多的字母 给出一个字符串,统计出现次数最多的字母.如:“wqeqwhixswiqhdxsq”,其中出现最多的是q. js算法的实现 function findMax(str) ...

  3. JS基础算法题(二)

    1.1 数组去重的五种方法 数组去重:将数组中重复的元素去掉 JS数组没有删除具体元素的删除(只能删掉值,删不掉元素的索引),可以使用另外一个结构来进行存储 新数组 新对象 JS数组虽然本质可以删除第 ...

  4. FCC JS基础算法题(5):Return Largest Numbers in Arrays(找出多个数组中的最大数)

    题目描述: 找出多个数组中的最大数右边大数组中包含了4个小数组,分别找到每个小数组中的最大值,然后把它们串联起来,形成一个新数组.提示:你可以用for循环来迭代数组,并通过arr[i]的方式来访问数组 ...

  5. FCC JS基础算法题(4):Title Case a Sentence(句中单词首字母大写)

    题目描述: 确保字符串的每个单词首字母都大写,其余部分小写.像'the'和'of'这样的连接符同理. 算法: function titleCase(str) { // 转小写及分割成数组 var st ...

  6. FCC JS基础算法题(2):Check for Palindromes(检查回文字符串)

    题目描述: 如果给定的字符串是回文,返回true,反之,返回false.如果一个字符串忽略标点符号.大小写和空格,正着读和反着读一模一样,那么这个字符串就是palindrome(回文).注意你需要去掉 ...

  7. FCC JS基础算法题(1):Factorialize a Number(计算一个整数的阶乘)

    题目描述: 如果用字母n来代表一个整数,阶乘代表着所有小于或等于n的整数的乘积.阶乘通常简写成 n!例如: 5! = 1 * 2 * 3 * 4 * 5 = 120. 算法: function fac ...

  8. FCC JS基础算法题(0):Reverse a String(翻转字符串)

    题目描述: 先把字符串转化成数组,再借助数组的reverse方法翻转数组顺序,最后把数组转化成字符串.你的结果必须得是一个字符串. 算法: function reverseString(str) { ...

  9. FCC JS基础算法题(10):Falsy Bouncer(过滤数组假值)

    题目描述: 删除数组中的所有假值.在JavaScript中,假值有false.null.0."".undefined 和 NaN. 使用filter方法,过滤掉生成的 Boolea ...

随机推荐

  1. mysql主从同步--读写分离。

    1.mysql 安装参考 https://www.cnblogs.com/ttzzyy/p/9063737.html 2. 主mysql,从mysql 指定配置文件启动 mysqld --defaul ...

  2. IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型

    原文: https://andrewlock.net/ihostingenvironment-vs-ihost-environment-obsolete-types-in-net-core-3/ 作者 ...

  3. 用本地自定义域名访问远程服务器,并支持websocket和cookie

    场景 在公司会有很多测试的机器,或者一些OA服务,Confluence,Jenkins,各种中间件的后台等等,都使用HTTP访问,且由于是内网机器没有域名,输入IP又要输入不同端口,访问起来比较麻烦. ...

  4. 1041 考试座位号 (15 分)C语言

    每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位.正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考 ...

  5. SqlBulkCopy批量插入和索引的关系

    .net中批量插入基本都用SqlBulkCopy,速度很快,但是这几天发现个问题,2000数据居然15s,百思不得其解.经过大量测试,发现过多的索引和索引碎片会严重影响插入速度,表的数据量大小反而不会 ...

  6. 《企业IT架构转型之道:阿里巴巴中台战略思想与架构实战》-总结

      一.什么是业务中台 概念来自于阿里,介于前台和后台(此后台指的是云计算.数据库.消息队列.缓存等基础服务) 采用共享式架构设计解决以往烟囱式架构设计的资源浪费.重复造轮.试错成本高的问题 阿里的中 ...

  7. 一次jvm调优过程

    jvm调优实战 前端时间把公司的一个分布式定时调度的系统弄上了容器云,部署在kubernetes,在容器运行的动不动就出现问题,特别容易jvm溢出,导致程序不可用,终端无法进入,日志一直在刷错误,ku ...

  8. 【Vue】强化表单的9个Vue输入库

    一个设计不当的表单可能会使用户远离你的网站.幸运的是,对Vue开发者,有大量可用的Vue输入库让你轻松整理表单. 拥有直观而且对用户友好的表单有诸多好处,比如: 更高的转化率 更好的用户体验 更专业的 ...

  9. Python学习,第六课 - 集合

    Python中集合的相关操作 集合是一个无序的,不重复的数据组合 它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 list_1 =set ...

  10. 小白学Java:File类

    目录 小白学Java:File类 不同风格的分隔符 绝对与相对路径 File类常用方法 常用构造器 创建方法 判断方法 获取方法 命名方法 删除方法 小白学Java:File类 我们可以知道,存储在程 ...