【题目】

将一个没有重复数字的数组中的数据构造一个二叉树
每个节点都是该子树的最大值
【要求】
时间复杂度为O(N)
【题解】
使用单调栈,栈的顺序是维持从大到小排序
通过使用单调栈,将数组中中所有数的左右比他大的数记录下来
当某个数既无左边比他大的数,有无右边比他大的数,则该数为全局最大,将其作为二叉树的根
然后,某数只有左比他大的数,或者右比他大的数,则该数直接挂在比他大的数的下面,
当某个数既有左比他大的数,又有右比他大的数,则挂在两个数中较小数的下面。
然后直接构成一棵树。

 #include <iostream>
#include <vector>
#include <deque>
#include <sstream> using namespace std; struct Node
{
int val;
Node* lchild;
Node* rchild;
Node(int a) :val(a), lchild(nullptr), rchild(nullptr) {}
}; void creatMaxTree(Node*& root, vector<int>v)
{//以下代码都是以数组的下角标为根据
vector<Node*>node;
vector<pair<int, int>>res;//存储每个数的左右大小的数
res.resize(v.size());
deque<int>d;//单调栈
for (int i = ; i < v.size(); ++i)
{
Node* p = new Node(v[i]);
node.push_back(p);//先生成相关的节点
while (!d.empty() && v[i] > v[d.back()])
{
int index = d.back();
d.pop_back();
if (d.empty())//有右大值,无左大值
res[index] = pair<int, int>(-, i);
else//有右大值和左大值
res[index] = pair<int, int>(d.back(), i);
}
d.push_back(i);
}
while (!d.empty())
{
int index = d.back();
d.pop_back();
if (d.empty())//即无右大值,又无左大值
res[index] = pair<int, int>(-, -);
else//无右大值有左大值
res[index] = pair<int, int>(d.back(), -);
}
for (int i = ; i < res.size(); ++i)
{
int a, b;
a = res[i].first;
b = res[i].second;
if (a == - && b == -)//即无右大值,又无左大值为根节点
root = node[i];
else if (a == - && b != -)
node[b]->rchild = node[i];
else if (a != - && b == -)
node[a]->lchild = node[i];
else if (v[a] > v[b])
node[b]->rchild = node[i];
else
node[a]->lchild = node[i];
}
} //打印树形状进行查看
class PrintTree
{
public:
void Print(Node* root)
{
cout << "The shape of tree is: " << endl;
cout << "=============================================================" << endl;
PrintShape(root, , "H", );
cout << "=============================================================" << endl;
}
void PrintShape(Node* root, int h, string c, int len)
{
if (root)
{
PrintShape(root->rchild, h + , "v", len);
string val;
stringstream ss;
ss << root->val;
ss >> val;
val = c + val + c;
int lenM = val.length();
int lenL = (len - lenM) / ;
int lenR = len - lenM - lenL;
val = getSpace(lenL) + val + getSpace(lenR);
cout << getSpace(h*len) + val << endl;
PrintShape(root->lchild, h + , "^", len);
} }
string getSpace(int num)
{
string space = " ";
for (int i = ; i < num; ++i)
space.append(" ");
return space;
}
}; void Test()
{
vector<int>v;
v = { ,,,,, };
Node* root = nullptr;
creatMaxTree(root, v);
PrintTree print;
print.Print(root);
}

左神算法书籍《程序员代码面试指南》——1_08构造数组的MaxTree的更多相关文章

  1. 程序员代码面试指南 IT名企算法与数据结构题目最优解

    原文链接 这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现.针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮 ...

  2. 《程序员代码面试指南》第一章 栈和队列 构造数组的MaxTree

    题目 给出一个无重复元素的数组,构造此数组的MaxTree, java代码 /** * @Description: 构造数组的MaxTree * @Author: lizhouwei * @Creat ...

  3. 程序员代码面试指南:IT名企算法与数据结构题目最优解

      第1章栈和队列 1设计一个有getMin功能的栈(士★☆☆☆) 1由两个栈组成的队列(尉★★☆☆) 5如何仅用递归函数和栈操作逆序一个栈(尉★★☆☆) 8猫狗队列(士★☆☆☆)10用一个栈实现另一 ...

  4. 左神算法书籍《程序员代码面试指南》——3_05Morris遍历二叉树的神级方法【★★★★★】

    [问题]介绍一种时间复杂度O(N),额外空间复杂度O(1)的二叉树的遍历方式,N为二叉树的节点个数无论是递归还是非递归,避免不了额外空间为O(h),h 为二叉树的高度使用morris遍历,即利用空节点 ...

  5. 左神算法书籍《程序员代码面试指南》——2_11将单链表的每K个节点之间逆序

    [题目]给定一个单链表的头节点head,实现一个调整单链表的函数,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点.例如:链表:1->2->3->4->5 ...

  6. 左神算法书籍《程序员代码面试指南》——1_01设计一个有getMin功能的栈

    [题目] 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. [要求] 1.pop.push.getMin操作的时间复杂度都是O(1).2.设计的栈类型可以使用现成的栈结构. ...

  7. 左神算法书籍《程序员代码面试指南》——2_03删除链表的中间节点和a/b处的节点

    [题目]给定链表的头节点head,实现删除链表的中间节点的函数.例如:不删除任何节点:1->2,删除节点1:1->2->3,删除节点2:1->2->3->4,删除节 ...

  8. 左神算法书籍《程序员代码面试指南》——2_02在单链表和双链表中删除倒数第k个字节

    [题目]分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点.[要求]如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1).[题解]从头遍历链表, ...

  9. 左神算法书籍《程序员代码面试指南》——1_10最大值减去最小值小于或等于num的子数组数量

    [题目]给定数组arr和整数num,共返回有多少个子数组满足如下情况:max(arr[i.j]) - min(arr[i.j]) <= num max(arfi.j])表示子数组ar[ij]中的 ...

随机推荐

  1. 豌豆荚Redis集群方案:Codis

    Codis简介 Codis是一个分布式Redis解决方案,对于上层的应用来说,连接到CodisProxy和连接原生的RedisServer没有明显的区别(不支持的命令列表),上层应用可以像使用单机的R ...

  2. 石子合并问题 /// 区间DP oj2025

    Description 在一个圆形操场的四周摆放着n堆石子.现要将石子有次序地合并成一堆. 规定每次只能选相邻的两堆石子合并成新的一堆,并将新得的这堆石子数记为该次合并的得分. 试设计一个算法,计算出 ...

  3. 7款外观迷人的HTML5/CSS3 3D特效按钮特效

    下面我整理了7款外观都十分迷人的HTML5/CSS3 3D按钮特效,有几个还挺实用的,分享给大家. 1.CSS3超酷3D弹性按钮 按钮实现非常简单 之前我们分享过几款不错的CSS3 3D立体按钮,比如 ...

  4. HTML-完美解决父子元素的外边距重叠和高度塌陷问题

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. 布局页中的特殊情况(比如说只有某页有的banner)

    仅作代码记录之用 /WEB-INF/tags/section.tag <%@ tag language="java" import="java.util.*,jav ...

  6. differential related impedance and termination

    Impedance (1) Z0 Z0 is the impedance of one T-line while other lines are held at 0. Single end. (2) ...

  7. RabbitMQ 五种工作模式

    官网介绍:https://www.rabbitmq.com/getstarted.html 五种工作模式的主要特点 简单模式:一个生产者,一个消费者 work模式:一个生产者,多个消费者,每个消费者获 ...

  8. Apache Flink 进阶(一):Runtime 核心机制剖析

    1. 综述 本文主要介绍 Flink Runtime 的作业执行的核心机制.首先介绍 Flink Runtime 的整体架构以及 Job 的基本执行流程,然后介绍在这个过程,Flink 是怎么进行资源 ...

  9. 期望——邮票收集问题lightoj1342

    邮票手机问题: 有n种类型的邮票,问将所有的类型的邮票全部收集起来所要的收集次数期望是多少. 设dp[i]为已经收集了i种类型的票,还要收集n-i种的次数的期望. dp[n]=0; 递推式: dp[i ...

  10. springboot与安全

    概念: 安全 Spring Security是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型.他可以实现强大的web安全控制.对于安全控制,我们仅需引入sprin ...