左神算法进阶班3_1构造数组的MaxTree

题目

一个数组的MaxTree定义:

  • 数组必须没有重复元素
  • MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点
  • 包括MaxTree树在内且在其中的每一棵子树上,值最大的节点都是树的头

给定一个没有重复元素的数组arr,写出生成这个数组的MaxTree的函数,要求如果数组长度为N,则时间负责度为O(N)、额外空间负责度为O(N)。

实现思路

  将数组按照大根堆进行排序
  然后直接按照大根堆进行构造一颗二叉树即可。
  使用单调栈
  通过使用单调栈,将数组中中所有数的左右比他大的数记录下来
  当某个数既无左边比他大的数,有无右边比他大的数,则该数为全局最大,将其作为二叉树的根
  然后,某数只有左比他大的数,或者右比他大的数,则该数直接挂在比他大的数的下面,
  当某个数既有左比他大的数,又有右比他大的数,则挂在两个数中较小数的下面。
  然后直接构成一棵树。
  右大值为右孩子,左大值为左孩子

代码

 1 void creatMaxTree(Node*& root, vector<int>v)
 2 {//以下代码都是以数组的下角标为根据
 3     vector<Node*>node;
 4     vector<pair<int, int>>res;//存储每个数的左右大小的数
 5     res.resize(v.size());
 6     deque<int>d;//单调栈
 7     for (int i = 0; i < v.size(); ++i)
 8     {
 9         Node* p = new Node(v[i]);
10         node.push_back(p);//先生成相关的节点
11         while (!d.empty() && v[i] > v[d.back()])
12         {
13             int index = d.back();
14             d.pop_back();
15             if (d.empty())//有右大值,无左大值
16                 res[index] = pair<int, int>(-1, i);
17             else//有右大值和左大值
18                 res[index] = pair<int, int>(d.back(), i);
19         }
20         d.push_back(i);
21     }
22     while (!d.empty())
23     {
24         int index = d.back();
25         d.pop_back();
26         if (d.empty())//即无右大值,又无左大值
27             res[index] = pair<int, int>(-1, -1);
28         else//无右大值有左大值
29             res[index] = pair<int, int>(d.back(), -1);
30     }
31     for (int i = 0; i < res.size(); ++i)
32     {
33         int a, b;
34         a = res[i].first;
35         b = res[i].second;
36         if (a == -1 && b == -1)//即无右大值,又无左大值为根节点
37             root = node[i];
38         else if (a == -1 && b != -1)
39             node[b]->rchild = node[i];
40         else if (a != -1 && b == -1)
41             node[a]->lchild = node[i];
42         else if (v[a] > v[b])
43             node[b]->rchild = node[i];
44         else
45             node[a]->lchild = node[i];
46     }
47 }

效果

The shape of tree is:
=============================================================
                          v5v
                                                            v3v
                                           ^4^
                                                            ^2^
         H6H
                          ^1^
=============================================================

原文地址:https://www.cnblogs.com/zzw1024/p/11052016.html

时间: 2024-11-10 07:32:40

左神算法进阶班3_1构造数组的MaxTree的相关文章

左神算法进阶班1_5BFPRT算法

在无序数组中找到第k大的数1)分组,每N个数一组,(一般5个一组)2)每组分别进行排序,组间不排序3)将每个组的中位数拿出来,若偶数,则拿上 / 下中位数, 成立一个一个新数组.4)新数组递归调用BFPRT,则拿到整体的中位数num5)以num来划分整体数组,小于在左,大于在右边,使用[荷兰国旗方法]6)然后根据左右数组的规模,来确定进一步选择左右哪一部分:7)然后选择好后,继续 一:背景介绍在一大堆数中求其前k大或前k小的问题,简称TOP - K问题.而目前解决TOP - K问题最有效的算法即

左神算法进阶班5_1求二叉树中最大搜索子树大小

[题目] 给定一棵二叉树的头节点head,请返回最大搜索二叉子树的大小 [题解] 简化问题,想到该问题的解答应该有几种情形 第一种可能: 最大搜索二叉子树在head的左子树 第二种可能: 最大搜索二叉子树在head的右子树 第三种可能: 最大搜索二叉子树为自己:利用左子树的最大值与右子树的最小值 递归左子树,再递归右子树 信息1:左子树中最大搜索二叉树的大小 信息2:右子树中最大搜索二叉树的大小 信息3:左子树最大搜索二叉树的头结点 信息4:右子树最大搜索二叉树的头结点 信息5:左子树上的最大值

左神算法进阶班1_1添加最少字符得到原字符N次

Problem: 给定一个字符串str1,只能往str1的后面添加字符变成str2. 要求1:str2必须包含两个str1,两个str1可以有重合,但是不能以同一个位置开头. 要求2:str2尽量短最终返回str2 举例: str1 = 123,str2 = 123123 时,包含两个str1,且不以相同位置开头,且str2最短. str1 = 123123,str2 = 123123123 时,包含两个str1,且不以相同位置开头,且str2最短. str1 = 111,str2 = 1111

左神算法进阶班5_3求公司的最大活跃度

[题目] 一个公司的上下节关系是一棵多叉树,这个公司要举办晚会,你作为组织者已经摸清了大家的心理: 一个员工的直接上级如果到场,这个员工肯定不会来. 每个员工都有一个活跃度的值,决定谁来你会给这个员工发邀请函,怎么让舞会的气氛最活跃? 返回最大的活跃值. 举例: 给定一个矩阵来表述这种关系 matrix = { 1,6 1,5 1,4 } 这个矩阵的含义是: matrix[0] = { 1 , 6 },表示0这个员工的直接上级为1, 0这个员工自己的活跃度为6 matrix[1] = { 1 ,

左神算法进阶班6_1LFU缓存实现

[题目] LFU也是一个著名的缓存算法,自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) [题解] LFU算法与LRU算法很像 但LRU是最新使用的排在使用频率最前面,也就是LRU是通过使用时间进行排序, 使用时间越新,其使用频率越高,而使用时间越久,其使用频率越低,即当空间满时,被删除的概率最大 而LFU是根据使用次数来算使用频率的,使用次数越多,其使用频率越高,使用次数越少,使用频率越低,当空间满时越容易被删除 同样,使用hash_map表和双向链表进行存

左神算法基础班3_13深度拷贝含有随机指针的链表

Problem: 复制含有随机指针节点的链表 [题目] 一种特殊的链表节点类描述如下: public class Node { public int value; public Node next; public Node rand; public Node(int data) { this.value = data; } } Node类中的value是节点值,next指针和正常单链表中next指针的意义 一 样,都指向下一个节点,rand指针是Node类中新增的指针,这个指 针可 能指向链表中

算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序

接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public int value; public Node left; public Node right; public Node(int data){ this.value=data; } } 一个数组的MaxTree定义如下: ◆ 数组必须没有重复元素 ◆ MaxTree是一颗二叉树,数组的每一个值对应一

构造数组的MaxTree

[说明]: 本文是左程云老师所著的<程序员面试代码指南>第一章中“构造数组的MaxTree”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书. 感谢左程云老师的支持. [题目]: 定义二叉树节点如下: class Node { public: Node(int data) { value = data; left = NULL; right = NULL; } public: int value; Node *left; No

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

题目 给出一个无重复元素的数组,构造此数组的MaxTree, java代码 /** * @Description: 构造数组的MaxTree * @Author: lizhouwei * @CreateDate: 2018/4/5 22:16 * @Modify by: * @ModifyDate: */ public class Chapter1_8 { public Node getMaxTree(int[] arr) { if (arr == null) { return null; }