[Leedcode][JAVA][第105题][从前序与中序遍历序列构造二叉树][栈][递归][二叉树]

【问题描述】[中等]

根据一棵树的前序遍历与中序遍历构造二叉树。注意:
你可以假设树中没有重复的元素。例如,给出前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:3/ \9  20/  \15   7

【解答思路】

1. 递归

先序遍历的顺序是根节点,左子树,右子树。中序遍历的顺序是左子树,根节点,右子树。
只需要根据先序遍历得到根节点,然后在中序遍历中找到根节点的位置,它的左边就是左子树的节点,右边就是右子树的节点。
在这里插入图片描述在这里插入图片描述
时间复杂度:O(N) 空间复杂度:O(N)

public TreeNode buildTree(int[] preorder, int[] inorder) {return buildTreeHelper(preorder, 0, preorder.length, inorder, 0, inorder.length);
}private TreeNode buildTreeHelper(int[] preorder, int p_start, int p_end, int[] inorder, int i_start, int i_end) {// preorder 为空,直接返回 nullif (p_start == p_end) {return null;}int root_val = preorder[p_start];TreeNode root = new TreeNode(root_val);//在中序遍历中找到根节点的位置int i_root_index = 0;for (int i = i_start; i < i_end; i++) {if (root_val == inorder[i]) {i_root_index = i;break;}}int leftNum = i_root_index - i_start;//递归的构造左子树root.left = buildTreeHelper(preorder, p_start + 1, p_start + leftNum + 1, inorder, i_start, i_root_index);//递归的构造右子树root.right = buildTreeHelper(preorder, p_start + leftNum + 1, p_end, inorder, i_root_index + 1, i_end);return root;
}

HashMap优化

public TreeNode buildTree(int[] preorder, int[] inorder) {HashMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < inorder.length; i++) {map.put(inorder[i], i);}return buildTreeHelper(preorder, 0, preorder.length, inorder, 0, inorder.length, map);
}private TreeNode buildTreeHelper(int[] preorder, int p_start, int p_end, int[] inorder, int i_start, int i_end,HashMap<Integer, Integer> map) {if (p_start == p_end) {return null;}int root_val = preorder[p_start];TreeNode root = new TreeNode(root_val);int i_root_index = map.get(root_val);int leftNum = i_root_index - i_start;root.left = buildTreeHelper(preorder, p_start + 1, p_start + leftNum + 1, inorder, i_start, i_root_index, map);root.right = buildTreeHelper(preorder, p_start + leftNum + 1, p_end, inorder, i_root_index + 1, i_end, map);return root;
}
2. 迭代 栈

用一个栈保存已经遍历过的节点,遍历前序遍历的数组,一直作为当前根节点的左子树,直到当前节点和中序遍历的数组的节点相等了,那么我们正序遍历中序遍历的数组,倒着遍历已经遍历过的根节点(用栈的 pop 实现),找到最后一次相等的位置,把它作为该节点的右子树。

代码细节

  • 用一个栈保存已经遍历的节点
  • 用 curRoot 保存当前正在遍历的节点
    在这里插入图片描述
    在这里插入图片描述
    时间复杂度:O(N) 空间复杂度:O(N)
public TreeNode buildTree(int[] preorder, int[] inorder) {if (preorder.length == 0) {return null;}Stack<TreeNode> roots = new Stack<TreeNode>();int pre = 0;int in = 0;//先序遍历第一个值作为根节点TreeNode curRoot = new TreeNode(preorder[pre]);TreeNode root = curRoot;roots.push(curRoot);pre++;//遍历前序遍历的数组while (pre < preorder.length) {//出现了当前节点的值和中序遍历数组的值相等,寻找是谁的右子树if (curRoot.val == inorder[in]) {//每次进行出栈,实现倒着遍历while (!roots.isEmpty() && roots.peek().val == inorder[in]) {curRoot = roots.peek();roots.pop();in++;}//设为当前的右孩子curRoot.right = new TreeNode(preorder[pre]);//更新 curRootcurRoot = curRoot.right;roots.push(curRoot);pre++;} else {//否则的话就一直作为左子树curRoot.left = new TreeNode(preorder[pre]);curRoot = curRoot.left;roots.push(curRoot);pre++;}}return root;
}
class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {if(preorder.length==0 || inorder.length==0) {return null;}//根据前序数组的第一个元素,就可以确定根节点TreeNode root = new TreeNode(preorder[0]);for(int i=0;i<preorder.length;++i) {//用preorder[0]去中序数组中查找对应的元素if(preorder[0]==inorder[i]) {//将前序数组分成左右两半,再将中序数组分成左右两半//之后递归的处理前序数组的左边部分和中序数组的左边部分//递归处理前序数组右边部分和中序数组右边部分int[] pre_left = Arrays.copyOfRange(preorder,1,i+1);int[] pre_right = Arrays.copyOfRange(preorder,i+1,preorder.length);int[] in_left = Arrays.copyOfRange(inorder,0,i);int[] in_right = Arrays.copyOfRange(inorder,i+1,inorder.length);root.left = buildTree(pre_left,in_left);root.right = buildTree(pre_right,in_right);break;}}return root;}
}作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/dong-hua-yan-shi-105-cong-qian-xu-yu-zhong-xu-bian/

【总结】

1.前中后序遍历变化的是[中]的位置,左到右的顺序不改变
  • 前序遍历 中左右
  • 中序遍历 左中右
  • 后续遍历 左右中
2.还原二叉树 借助HashMap or copyOfRange

根据前序和后序遍历构造二叉树
[Leetcode][第889题][JAVA][根据前序和后序遍历构造二叉树][分治][递归]
前序+中序遍历可画出原二叉树
[Leedcode][JAVA][第105题][从前序与中序遍历序列构造二叉树][栈][递归][二叉树]
后续+中序遍历可画出原二叉树
[Leetcode][第106题][JAVA][ 从中序与后序遍历序列构造二叉树][分治][递归]

3. 多画图 写写写 遍历代码 手撕变量 大脑保持清醒

转载链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–22/

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

登录页面实现

实现登录页面 打开NetBeans&#xff0c;创建Java Web项目 <hr><hr> <form name"" action "" method"post"> <table border"1"> <tr> <td>用户名&#xff1a;</td> …

html和css可以用在ssh里面么,在网站中使用SSH

嗨&#xff0c;我目前正在制作自己的软件来控制一个带有Raspberry Pi的机器人。我想知道是否可以将ssh嵌入到HTML代码中&#xff0c;因此当用户输入Pi的IP地址时&#xff0c;它将通过ssh连接到pi。在网站中使用SSH然后我想要做的是通过ssh发送命令&#xff0c;当他们点击一个按…

JSP环境简介

JSP环境简介 最低环境需求 JDK jdk的安装和配置

[Leedcode][JAVA][第680题][验证回文字符串Ⅱ][贪心][递归]

【问题描述】[第680题][验证回文字符串Ⅱ][简单] 给定一个非空字符串 s&#xff0c;最多删除一个字符。判断是否能成为回文字符串。示例 1:输入: "aba" 输出: True 示例 2:输入: "abca" 输出: True 解释: 你可以删除c字符。 注意:字符串只包含从 a-z 的小…

html:(2):制作第一个网页和html和css的关系

在<h1>和</h1>标签之间&#xff0c;输入Hello World 字符串。 <!DOCTYPE HTML> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8"><title>制作我的第一个网页</title><…

随手练——洛谷-P1008 / P1618 三连击(暴力搜索)

1.普通版 第一眼看到这个题&#xff0c;我脑海里就是&#xff0c;“我们是不是在哪里见过~”&#xff0c;去年大一刚学C语言的时候写过一个类似的题目&#xff0c;写了九重循环。。。。就像这样&#xff08;在洛谷题解里看到一位兄台写的。。。。超长警告&#xff0c;慎重点开&…

Java基础知识面试题

Java基础知识面试题Java概述基础语法数据类型编码注释访问修饰符关键字 final this super static流程控制语句面向对象类和接口变量和方法内部类重写与重载对象相等判断值传递Java包IO流反射String相关包装类相关Java概述 JVM、JRE和JDK的关系 JVM Java Virtual Machine是Jav…

html:(3):认识html标签和标签的语法

让我们通过一个网页的学习&#xff0c;来对html标签有一个初步理解。平常大家说的上网就是浏览各种各式各样的网页&#xff0c;这些网页都是由html标签组成的。下面就是一个简单的网页。效果图如下&#xff1a; 我们来分析一下&#xff0c;这个网页由哪些html标签组成&#xff…

JPA-EntityManager.merge()

EntityManager#merge merge() 用于处理 Entity 的同步。即数据库的插入和更新操作 merge的几种情况 1. 若传入的是一个临时对象 package jpa.test;import com.jpa.entity.Customer; import org.junit.After; import org.junit.Before; import org.junit.Test;import javax.pers…

[Leedcode][JAVA][第76题][最小覆盖子串]滑动窗口]

【问题描述】[第76题][最小覆盖子串][中等] 给你一个字符串 S、一个字符串 T&#xff0c;请在字符串 S 里面找出&#xff1a;包含 T 所有字符的最小子串。示例&#xff1a;输入: S "ADOBECODEBANC", T "ABC" 输出: "BANC" 说明&#xff1a;如…

计算机应用综合实践实验心得,综合实践活动培训心得体会范文(精选5篇)

综合实践活动培训心得体会范文(精选5篇)在平日里&#xff0c;心中难免会有一些新的想法&#xff0c;有这样的时机&#xff0c;要好好记录下来&#xff0c;这样能够让人头脑更加清醒&#xff0c;目标更加明确。怎样写好心得体会呢&#xff1f;下面是小编为大家整理的综合实践活动…

html:(4):认识html文件基本结构和认识head标签

认识html文件基本结构 这一节中我们来学习html文件的结构&#xff1a;一个HTML文件是有自己固定的结构的。 <html><head>...</head><body>...</body> </html> 代码讲解&#xff1a; 1. <html></html>称为根标签&#xff0…

[Leedcode][JAVA][第4题][寻找两个正序数组中的中位数][二分查找][双指针]

【问题描述】[困难] 给定两个大小为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出这两个正序数组的中位数&#xff0c;并且要求算法的时间复杂度为 O(log(m n))。你可以假设 nums1 和 nums2 不会同时为空。示例 1:nums1 [1, 3] nums2 [2]则…

html:(5):了解html的代码注释和语义化

了解HTML的代码注释 什么是代码注释&#xff1f;代码注释的作用是帮助程序员标注代码的用途&#xff0c;过一段时间后再看你所编写的代码&#xff0c;就能很快想起这段代码的用途。代码注释不仅方便程序员自己回忆起以前代码的用途&#xff0c;还可以帮助其他程序员很快的读懂…

[Leedcode][JAVA][第287题][寻找重复数][HashSet][二分查找][快慢指针]

【问题描述】[中等] 给定一个包含 n 1 个整数的数组 nums&#xff0c;其数字都在 1 到 n 之间&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。假设只有一个重复的整数&#xff0c;找出这个重复的数。输入: [1,3,4,2,2] 输出: 2说明&#xff1a…

html:(6):body标签和p标签

<body>标签&#xff0c;网页上显示的内容放在这里 还记得body标签吗&#xff0c;在上一章节我们简单介绍过&#xff1a;在网页上要展示出来的页面内容一定要放在body标签中。如下图是一个新闻文章的网页。 在浏览器中的显示效果&#xff1a; <!DOCTYPE HTML> <h…

[Leedcode][JAVA][第974题][和可被K整除的子数组][前缀和][HashSet]

【问题描述】[中等] 给定一个整数数组 A&#xff0c;返回其中元素之和可被 K 整除的&#xff08;连续、非空&#xff09;子数组的数目。示例&#xff1a;输入&#xff1a;A [4,5,0,-2,-3,1], K 5 输出&#xff1a;7 解释&#xff1a; 有 7 个子数组满足其元素之和可被 K 5 …

html:(7):了解hx标签和加强语气

了解<hx>标签&#xff0c;为你的网页添加标题 文章的段落用<p>标签&#xff0c;那么文章的标题用什么标签呢&#xff1f;在本节我们将使用<hx>标签来制作文章的标题。 标题标签一共有6个&#xff0c;h1、h2、h3、h4、h5、h6分别为一级标题、二级标题、三级标…

html:(8):span标签和q标签

使用<span>标签为文字设置单独样式 这一小节讲解<span>标签&#xff0c;我们对<em>、<strong>、<span>这三个标签进行一下总结&#xff1a; 1. <em>和<strong>标签是为了强调一段话中的关键字时使用&#xff0c;它们的语义是强调。…

cs20_1-1

1. 基本特点 1.1 save computation(惰性运行) x 2 y 3 add_op tf.add(x, y) mul_op tf.multiply(x, y) useless tf.multiply(x, add_op) pow_op tf.pow(add_op, mul_op) with tf.Session() as sess:z sess.run(pow_op) 如上&#xff0c;因为sess.run(pow_op)不需要用到u…