首页>>前端>>JavaScript->柿子带你刷 二叉树(leetcode实战篇)

柿子带你刷 二叉树(leetcode实战篇)

时间:2023-12-02 本站 点击:0

二叉树实战

知识补充

(如果不是我这种对二叉树没什么概念的小菜鸡,直接到最底下去看看 [105]从前序与中序遍历序列构造二叉树的解题思路吧!)

在刷这道题之前,我们应该理解一下如何快速的从前序遍历、中序遍历、后序遍历【1】

前序遍历:

前序遍历的遍历方式呢:根、左、右(根节点、和他的左右节点)

中序遍历:

中序遍历的遍历方式呢:左、根、右

后序遍历:

中序遍历的遍历方式呢:左、右、根

根据这个规则我们利用下面的这个例子简单的来做一个练习:

根据下面的二叉树,快速进行前序、后序、中序的序列遍历吧:

前序(根、左、右):A B C D E F G H I

中序(左、根、右):C B D A G F H E I

后序(左、右、根):C D B G H F I E A

实战

光说不练假把式,说了这么多,没有用js实现都是纸上谈兵

二叉树的构造函数

function TreeNode(val, left, right) {    this.val = (val===undefined ? 0 : val)    this.left = (left===undefined ? null : left)    this.right = (right===undefined ? null : right)}

前序遍历

二叉树的前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 **遍历。

输入:root = [1,null,2,3] 输出:[1,2,3]

输入:root = [] 输出:[]

输入:root = [1] 输出:[1]

输入:root = [1,2] 输出:[1,2]

那么这道题的解题思路就很简单了

按照根-左-右的方式进行遍历就好

var preorderTraversal = function(root) {    const res = []    preorder(root, res)    return res};const preorder = (root, res) => {    if(root == null){        return    }    res.push(root.val)    preorder(root.left, res)    preorder(root.right, res)}

中序遍历

94. 二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

输入:root = [1,null,2,3] 输出:[1,3,2]

输入:root = [] 输出:[]

输入:root = [1] 输出:[1]

按照左、根、右的方式进行遍历就好

var inorderTraversal = function (root) {  const res = []  inorder(root, res)  return res};const inorder = (root, res) => {  if (root == null) {    return  }  inorder(root.left, res)  res.push(root.val)  inorder(root.right, res)}

仔细一看代码有没有一种???似曾相识的感觉? 不错,我们就仅仅换了一个位置罢了!

后序遍历

145. 二叉树的后序遍历

一样我们记住公式和顺序,换汤不换药

按照 左、右、根

var postorderTraversal = function(root) {  const res = []  postorder(root, res)  return res};// 按照左、右、根的顺序来就好const postorder = (root,res) => {  if(root === null){    return  }  postorder(root.left, res)  postorder(root.right, res)  res.push(root.val)}

到这里我们的前中后遍历大家就都应该简单懂了吧!

接下来。。。。。重头戏上场!

从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例 1:

输入 : preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]输出: [3,9,20,null,null,15,7]

示例 2:

输入: preorder = [-1], inorder = [-1]输出: [-1]

思路

我们需要紧紧抓住前序遍历序列和中序遍历序列的定义

前序遍历序列的第一个元素就是树的根节点

前序遍历的节点元素的后面的元素 先是左子树的所有节点而后是右子树的所有节点

3 是二叉树的根节点

[9] 则是 二叉树的左子树的所有节点

[20,15,7]是右子树的所有节点

用示例 1举个例子[3,9,20,15,7]

中序遍历中,根节点把中序遍历序列分成了两个部分,左边部分构成了二叉树的根节点的左子树,右边则是右子树

3 是二叉树的根节点

[9] 则是 二叉树的左子树的所有节点

[15,20,7]是右子树的所有节点

举示例 1个例子[9,3,15,20,7]

那我们的思路就有了:

我们可以根据当前前序遍历的第一个元素获取当前二叉树的根节点

利用二叉树的根节点 找到中序遍历的时候的位置,在中序遍历和前序遍历的时候,也就是节点的位置不同,但是左右节点的个数是相同的

这样我们就能确定他的左节点有多少,和右节点有多少个

这样我们就可以通过 parentIndex = inorder.indexOf(preorder[0]) 来获取切分左右节点的个数的位置

左节点:preorder.slice(1, parentIndex + 1)

右节点:preorder.slice(parentIndex + 1)

解法

var buildTree = function(preorder, inorder) {  if(inorder.length === 0 || preorder.length === 0){    return null  }  const res = new TreeNode(preorder[0])  const parentIndex = inorder.indexOf(preorder[0])  res.left = buildTree(preorder.slice(1, parentIndex + 1), inorder.slice(0, parentIndex))  res.right = buildTree(preorder.slice(parentIndex + 1), inorder.slice(parentIndex + 1))  return res};

解析:

我们通过slice 每次就传入当前节点的左/右子节点元素的数组,所以我们可以确定,前序序列的数组的第一项肯定就是当前这个二叉树节点的根节点。

利用这个根节点我们通过查询中序序列的位置,我们可以得到这个根节点的左/右节点数组。

递归查询,即可

知识点归纳

【1】前序遍历 中序遍历 后序遍历

【2】105. 从前序与中序遍历序列构造二叉树 Construct Binary Tree from Preorder and Inorder Traversal

优秀博文推荐

东哥带你刷二叉树

原文:https://juejin.cn/post/7101685412069900301


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/JavaScript/9509.html