2021-06-12:已知一棵搜索二叉树上没有重复值的节点,现在有一个数组arr,是这棵搜索二叉树先序遍历的结果。请根据arr生成整棵树并返回头节点。
2021-06-12:已知一棵搜索二叉树上没有重复值的节点,现在有一个数组arr,是这棵搜索二叉树先序遍历的结果。请根据arr生成整棵树并返回头节点。
福大大 答案2021-06-12:
先序遍历+中序遍历(搜索树)+不重复值=唯一的二叉树。
解法一
自然智慧。第0位置为根节点,遍历1~N-1位置,找到比0位置大的,那就是属于根的右节点。时间复杂度是O(N**2)。
解法二
单调栈。时间复杂度是O(N)。
代码用golang编写。代码如下:
package main
import (
"container/list"
"fmt"
)
func main() {
arr := []int{8, 5, 1, 7, 10, 12}
ret1 := bstFromPreorder1(arr)
fmt.Println("----自然智慧----")
printTree(ret1)
fmt.Println("")
fmt.Println("----单调栈----")
ret2 := bstFromPreorder2(arr)
printTree(ret2)
}
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func printTree(head *TreeNode) {
if head == nil {
return
}
queue := list.New()
queue.PushBack(head)
for queue.Len() > 0 {
before := queue.Front()
queue.Remove(before)
beforeNode := before.Value.(*TreeNode)
fmt.Print(beforeNode.Val, "\t")
if beforeNode.Left != nil {
queue.PushBack(beforeNode.Left)
}
if beforeNode.Right != nil {
queue.PushBack(beforeNode.Right)
}
}
}
func bstFromPreorder1(pre []int) *TreeNode {
return process1(pre, 0, len(pre))
}
func process1(pre []int, start int, endnot int) *TreeNode {
if start == endnot {
return nil
}
if start+1 == endnot {
return &TreeNode{Val: pre[start]}
}
i := start + 1
for ; i < endnot; i++ {
if pre[start] < pre[i] {
break
}
}
head := &TreeNode{Val: pre[start]}
head.Left = process1(pre, start+1, i)
head.Right = process1(pre, i, endnot)
return head
}
// 已经是时间复杂度最优的方法了,但是常数项还能优化
func bstFromPreorder2(pre []int) *TreeNode {
if len(pre) == 0 {
return nil
}
N := len(pre)
nearBig := make([]int, N)
for i := 0; i < N; i++ {
nearBig[i] = -1
}
stack := list.New()
for i := 0; i < N; i++ {
for stack.Len() > 0 && pre[stack.Back().Value.(int)] < pre[i] {
nearBig[stack.Back().Value.(int)] = i
stack.Remove(stack.Back())
}
stack.PushBack(i)
}
return process2(pre, 0, N-1, nearBig)
}
func process2(pre []int, L int, R int, nearBig []int) *TreeNode {
if L > R {
return nil
}
firstBig := twoSelectOne(nearBig[L] == -1 || nearBig[L] > R, R+1, nearBig[L])
head := &TreeNode{Val: pre[L]}
head.Left = process2(pre, L+1, firstBig-1, nearBig)
head.Right = process2(pre, firstBig, R, nearBig)
return head
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
执行结果如下:

2021-06-12:已知一棵搜索二叉树上没有重复值的节点,现在有一个数组arr,是这棵搜索二叉树先序遍历的结果。请根据arr生成整棵树并返回头节点。的更多相关文章
- JAVA-集合作业-已知有十六支男子足球队参加2008 北京奥运会。写一个程序,把这16 支球队随机分为4 个组。采用List集合和随机数
第二题 已知有十六支男子足球队参加2008 北京奥运会.写一个程序,把这16 支球队随机分为4 个组.采用List集合和随机数 2008 北京奥运会男足参赛国家: 科特迪瓦,阿根廷,澳大利亚,塞尔维亚 ...
- 2021.06.12【NOIP提高B组】模拟 总结
T1 题目大意:有 \(n\) 个点,到点 \(i\) 可以获得 \(A_i\) ,同时消耗 \(B_i\) 若当前价值小于 \(B_i\) 则不能到,问从 \(P\) 开始,任一点结束后的最大值. ...
- 第二题 已知有十六支男子足球队参加2008 北京奥运会。写一个程序,把这16 支球队随机分为4 个组。采用List集合和随机数 2008 北京奥运会男足参赛国家: 科特迪瓦,阿根廷,澳大利亚,塞尔维亚,荷兰,尼日利亚、日本,美国,中国,新西 兰,巴西,比利时,韩国,喀麦隆,洪都拉斯,意大利
import java.util.ArrayList; import java.util.List; import java.util.Random; public class List1 { pub ...
- 第二题 已知有十六支男子足球队参加2008 北京奥运会。写一个程序,把这16 支球队随机分为4 个组。采用List集合和随机数 2008 北京奥运会男足参赛国家: 科特迪瓦,阿根廷,澳大利亚,塞尔维亚,荷兰,尼日利亚、日本,美国,中国,新西 兰,巴西,比利时,韩国,喀麦隆,洪都拉斯,意大利
package com.hanqi.test; import java.util.ArrayList; import java.util.List; import java.util.Random; ...
- 已知有十六支男子足球队参加2008 北京奥运会。写一个程序,把这16 支球队随机分为4 个组。采用List集合和随机数
package homework002; import java.util.ArrayList; import java.util.List; import java.util.Random; p ...
- [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)
原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...
- 【美国血统 American Heritage 题解】已知前序中序 求后序
题目: 题目名称:美国血统 American Heritage 题目来源:美国血统 American Heritage ## 题目描述 农夫约翰非常认真地对待他的奶牛们的血统.然而他不是一个真正优秀的 ...
- 【PAT甲级】1119 Pre- and Post-order Traversals (30分)(已知先序后序输出是否二叉树唯一并输出中序遍历)
题意: 输入一个正整数N(<=30),接着输入两行N个正整数第一行为先序遍历,第二行为后续遍历.输出是否可以构造一棵唯一的二叉树并输出其中一颗二叉树的中序遍历. trick: 输出完毕中序遍历后 ...
- C语言:已知三角形三边长求面积
//已知三角形三边长求面积 #include <stdio.h> #include <math.h> int main() { float a,b,c,p,s; int x=0 ...
- 6.二元查找树的后序遍历结果[PostOrderOfBST]
[题目] 输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果: 8 ...
随机推荐
- Python--相关环境的安装,以及hello world的实现
相关环境 进入官网:https://www.python.org/downloads/ 点击这里: 来到新的界面之后,向下滑动: 找到上图中的界面,选择版本进行下载即可. 具体的安装步骤可以参考这里看 ...
- 报错的大怨种来了--java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
频繁爆出这样的错误:java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual t ...
- day02-容器功能
容器功能 1.Spring注入组件的注解 Spring中的传统注解@Component.@Controller.@Service.@Repository,在SpringBoot中仍然有效. 2.@Co ...
- 声网 X 远程超声:实时音视频解决基层“看病难” 推动医疗资源均衡化
实时互联网像触角一样,通过情景的共享延伸开来,链接着我们彼此的线下.线上生活,形成一张不可分割的网络.随着社交直播.在线教育.视频会议成为大众生活不可或缺的一部分的同时,智能手表.智能作业灯.视频双录 ...
- 【手搓模型】亲手实现 Vision Transformer
前言 博客主页:睡晚不猿序程 首发时间:2023.3.17,首发于博客园 最近更新时间:2023.3.17 本文由 睡晚不猿序程 原创 作者是蒻蒟本蒟,如果文章里有任何错误或者表述不清,请 tt 我, ...
- C语言 ini 文件读写【Iniparser库】
一.概述 iniparser是针对INI文件的解析器.ini文件则是一些系统或者软件的配置文件.iniparser库的API可以对ini文件(配置文件)进行解析.设置.删除等操作. 常见的 ini 读 ...
- Python——高级数据类型(七)
1. 列表数据类型的声明与访问 # coding=utf-8 #列表数据类型的声明与访问 my_list =[1,2,3,4,5] # 列表中的元素 print (my_list) # 0 1 2 3 ...
- 使用golang+antlr4构建一个自己的语言解析器(一)
Antlr4 简介 ANTLR(全名:ANother Tool for Language Recognition)是基于LL(*)算法实现的语法解析器生成器(parser generator),用Ja ...
- 微信小程序登录页左上角的home图标如何隐藏?wx.hideHomeButton()不生效?
在做微信小程序时,我们一般都会在app.js中去判断当前用户是否已经登录,如果已经登录,会直接跳转到小程序的首页.如果未登录那么直接跳转登录页. 此时我们需要把首页首页作为微信小程序的pages列表中 ...
- [ACM]TL-Kruskal
#include<iostream> #include<cstdio> using namespace std; struct edge { int u; int v; int ...