【题目】

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

  1. #include <iostream>
  2. #include <vector>
  3. #include <deque>
  4. #include <sstream>
  5.  
  6. using namespace std;
  7.  
  8. struct Node
  9. {
  10. int val;
  11. Node* lchild;
  12. Node* rchild;
  13. Node(int a) :val(a), lchild(nullptr), rchild(nullptr) {}
  14. };
  15.  
  16. void creatMaxTree(Node*& root, vector<int>v)
  17. {//以下代码都是以数组的下角标为根据
  18. vector<Node*>node;
  19. vector<pair<int, int>>res;//存储每个数的左右大小的数
  20. res.resize(v.size());
  21. deque<int>d;//单调栈
  22. for (int i = ; i < v.size(); ++i)
  23. {
  24. Node* p = new Node(v[i]);
  25. node.push_back(p);//先生成相关的节点
  26. while (!d.empty() && v[i] > v[d.back()])
  27. {
  28. int index = d.back();
  29. d.pop_back();
  30. if (d.empty())//有右大值,无左大值
  31. res[index] = pair<int, int>(-, i);
  32. else//有右大值和左大值
  33. res[index] = pair<int, int>(d.back(), i);
  34. }
  35. d.push_back(i);
  36. }
  37. while (!d.empty())
  38. {
  39. int index = d.back();
  40. d.pop_back();
  41. if (d.empty())//即无右大值,又无左大值
  42. res[index] = pair<int, int>(-, -);
  43. else//无右大值有左大值
  44. res[index] = pair<int, int>(d.back(), -);
  45. }
  46. for (int i = ; i < res.size(); ++i)
  47. {
  48. int a, b;
  49. a = res[i].first;
  50. b = res[i].second;
  51. if (a == - && b == -)//即无右大值,又无左大值为根节点
  52. root = node[i];
  53. else if (a == - && b != -)
  54. node[b]->rchild = node[i];
  55. else if (a != - && b == -)
  56. node[a]->lchild = node[i];
  57. else if (v[a] > v[b])
  58. node[b]->rchild = node[i];
  59. else
  60. node[a]->lchild = node[i];
  61. }
  62. }
  63.  
  64. //打印树形状进行查看
  65. class PrintTree
  66. {
  67. public:
  68. void Print(Node* root)
  69. {
  70. cout << "The shape of tree is: " << endl;
  71. cout << "=============================================================" << endl;
  72. PrintShape(root, , "H", );
  73. cout << "=============================================================" << endl;
  74. }
  75. void PrintShape(Node* root, int h, string c, int len)
  76. {
  77. if (root)
  78. {
  79. PrintShape(root->rchild, h + , "v", len);
  80. string val;
  81. stringstream ss;
  82. ss << root->val;
  83. ss >> val;
  84. val = c + val + c;
  85. int lenM = val.length();
  86. int lenL = (len - lenM) / ;
  87. int lenR = len - lenM - lenL;
  88. val = getSpace(lenL) + val + getSpace(lenR);
  89. cout << getSpace(h*len) + val << endl;
  90. PrintShape(root->lchild, h + , "^", len);
  91. }
  92.  
  93. }
  94. string getSpace(int num)
  95. {
  96. string space = " ";
  97. for (int i = ; i < num; ++i)
  98. space.append(" ");
  99. return space;
  100. }
  101. };
  102.  
  103. void Test()
  104. {
  105. vector<int>v;
  106. v = { ,,,,, };
  107. Node* root = nullptr;
  108. creatMaxTree(root, v);
  109. PrintTree print;
  110. print.Print(root);
  111. }

左神算法书籍《程序员代码面试指南》——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. 02-Nov-2017 07:11:56.475 信息 [http-nio-8080-exec-10] com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource. Initializing c3p0 pool...

    报错: 02-Nov-2017 07:11:56.475 信息 [http-nio-8080-exec-10] com.mchange.v2.c3p0.impl.AbstractPoolBackedD ...

  2. day 84 Vue学习六之axios、vuex、脚手架中组件传值

    Vue学习六之axios.vuex.脚手架中组件传值   本节目录 一 axios的使用 二 vuex的使用 三 组件传值 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 axios的 ...

  3. Apache服务器性能如何优化

    配置网站,要充分的把系统资源利用出去,榨干系统的一切潜能,让网站速度发挥到极致.Apache,是用户浏览和网站数据的一个中间桥梁.但是在这里,我们虽然做得并不是很多,但是如果心细打理,有些设置也会起到 ...

  4. spring-data-JPA repository自定义方法规则

    一.自定义方法的规则 Spring Data JPA框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如find,findBy,read,readBy,get,getBy,然后对剩下的部分进行解 ...

  5. 移植 thttpd Web 服务器

    下载 从 http://www.acme.com/software/thttpd/下载 thttpd 到/tmp 目录当中,并解压. 编译 thttpd [arm@localhost thttpd­2 ...

  6. gdb调试工具的使用

    GDB是一个由GNU开源组织发布的.UNIX/LINUX操作系统下的.基于命令行的.功能强大的程序调试工具. GDB中的命令固然很多,但我们只需掌握其中十个左右的命令,就大致可以完成日常的基本的程序调 ...

  7. token 与 基于JWT的Token认证

    支持跨域访问,无状态认证 token特点 支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输 无状态(也称:服务端可扩展行): ...

  8. Django之深入了解模板层

    目录 模板语法 模板传值 过滤器 标签 自定义过滤器和标签 模板继承 模板导入 模板语法 前端模板的语法只记住两种就行了. {{ xxx }} 变量相关的 { % % } 逻辑相关的 模板传值 我们通 ...

  9. duilib教程之duilib入门简明教程3.第一个程序 Hello World

    小伙伴们有点迫不及待了么,来看一看Hello World吧:新建一个空的win32项目,新建一个main.cpp文件,将以下代码复制进去: #include <windows.h> #in ...

  10. 洛谷 P3120 [USACO15FEB]牛跳房子(金)Cow Hopscotch (Gold)

    P3120 [USACO15FEB]牛跳房子(金)Cow Hopscotch (Gold) 就像人类喜欢跳格子游戏一样,FJ的奶牛们发明了一种新的跳格子游戏.虽然这种接近一吨的笨拙的动物玩跳格子游戏几 ...