构造MaxTree

构造MaxTree

题目描述

对于一个没有重复元素的整数数组,请用其中元素构造一棵MaxTree,MaxTree定义为一棵二叉树,其中的节点与数组元素一一对应,同时对于MaxTree的每棵子树,它的根的元素值为子树的最大值。现有一建树方法,对于数组中的每个元素,其在树中的父亲为数组中它左边比它大的第一个数和右边比它大的第一个数中更小的一个。若两边都不存在比它大的数,那么它就是树根。请证明这个方法的正确性,同时设计O(n)的算法实现这个方法。

给定一个无重复元素的数组A和它的大小n,请返回一个数组,其中每个元素为原数组中对应位置元素在树中的父亲节点的编号,若为根则值为-1。

测试样例:
[3,1,4,2],4
返回:[2,0,-1,2]
 
 


算法的证明左神的书中解释的很详细,大致:
1. 该方法可以生成一棵树 不会是森林(所有元素都不同 向上总会有一个共同的最大值)
2. 该方法,所有元素最多只有两个孩子。(只需证明每个数一侧只会最多有一个孩子)

关于算法的复杂度:时间O(n) 空间O(n)
C++代码如下:
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
vector< int > buildMaxTree(vector< int > A, int n) {
         if (n <= 0){
             return vector< int >();
         }
         vector< int > res;  // 数组元素在树中父亲节点的编号
         stack< int > s;     // 栈 以递减方式存放元素值的位置index
 
         for ( int i = 0; i < n; ++i){
             int pos = -1; // 根编号为-1
 
             // 当前访问的元素比栈顶大 栈中元素需要出栈
             while (!s.empty() && A[i] > A[s.top()]){
                 int tmp = s.top();s.pop();
 
                 if (res[tmp] == -1 || A[i] < A[res[tmp]]){
                     res[tmp] = i;
                 }
             }
             // 找到了最近的比A[i]大的数
             if (!s.empty()){
                 pos = s.top();
             }
 
             s.push(i);
             res.push_back(pos);
         }
 
         return res;
     }
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值