这是我目前最喜欢的codiltiy上的问题之一。问题描述是:给定一个整数数组A,所有的数均不相同。假设下标从0开始,找到一个数组B, 满足A[B[0]] > A[B[1]] > A[B[2]] >...A[B[K]],对任意两项A[B[i]]和A[B[i + 1]],任意j,  min(B[i],B[i + 1]) < j < max(B[i],B[i + 1]) 均有A[j] < A[B[i + 1]] ,求最大的K。

例如,对数组 A,

A[0]  =  9   A[1]  = 10   A[2]  =  2
A[3] = -1 A[4] = 3 A[5] = -5
A[6] = 0 A[7] = -3 A[8] = 1
A[9] = 12 A[10] = 5 A[11] = 8
A[12] = -2 A[13] = 6 A[14] = 4

求得的数组B为 9,1,4,8,6,7,长度为6

 A[9] = 12    A[1] = 10    A[4] =  3
A[8] = 1 A[6] = 0 A[7] = -3

输入数组A的长度n [1..10^5],数组元素范围[-10^9,+10^9],都是整数且不相同。

要求复杂度 时间空间都是O(n)。

分析: 这个题乍一看没思路。需要转换:我们把A中得数建成一个类似”堆“的结构。对A数组,这个二叉树的根是最大值,然后我们把最大值两边的部分分别建立成这样的二叉树(每段递归的找最大值)。我们暂时抛开建树的复杂度,如果有了这样的树,我们所以的B数组长度对应为从树根到叶子的叶子的一条路径长度。(因为每个子树的根都是最大值)。那么如何建立这样的树呢? 暴力递归的方法会导致O(n^2)的复杂度。如果我们从做到右扫描A数组,假设某个值是当前最大值,它的左子树所有的元素都确定了,再出现的数,要么放在它的右子树,要么它成为别人的左子树。对于任意一个元素来讲,要么它成为之前元素的右子树,要么之前某个元素成为它的左子树,这取决于大小关系。我们在算一个元素的右子树的时候,因为元素还没扫描完,所以我们很难确定什么时候把它作为某个元素的右子树位置。 我们可以保存这样一个栈,栈的每个元素是一棵树,树根的左子树已经完全确定,根的右子树暂时是空。当弹出一棵树的时候,我们需要把它下面那个元素的子树合并。

也就是说,栈考顶得元素是其下面元素的右子树,但是右子树会变化。

大概过程如下:

如果当前元素比栈顶元素大,就把栈顶元素弹出,新弹出的元素作为之前弹出元素的右子树,都弹出之后形成的树,作为当前元素的左子树(右子树为空),形成的树放入栈。因为弹出来的东西都比当前元素小,并且在当前元素的左边。另外,我们不会真得合并树,只记录树的高度即可(根到叶子的节点个数)。代码非常简单:

// you can also use includes, for example:
// #include <algorithm>
int solution(const vector<int> &A) {
// write your code here...
int i, height, n = A.size();
vector<pair<int,int> > s;
for (i = 0; i < n; ++i) {
for (height = 0; (!s.empty()) && (s.back().first < A[i]);s.pop_back()) {
height = max(height + 1, s.back().second);
}
s.push_back(make_pair(A[i], height + 1));
}
for (height = 0; !s.empty();s.pop_back()) {
height = max(height + 1, s.back().second);
}
return height;
}

codility上的问题 (21) Upsilon 2012的更多相关文章

  1. codility上的问题(15) Xi 2012

    进入2012年的题 codility上的题目开始变难,变得有意思起来.给定两个长度在[1..300000]的只包含0和1的串S和T,它们是2进制表示的,S表示的数A不大于T表示的数B,即A<=B ...

  2. codility上的练习 (1)

    codility上面添加了教程.目前只有lesson 1,讲复杂度的……里面有几个题, 目前感觉题库的题简单. tasks: Frog-Jmp: 一只青蛙,要从X跳到Y或者大于等于Y的地方,每次跳的距 ...

  3. codility上的问题 (19)Sigma 2012

    题目: 像最大直方图一样给定一个数组是每个单位长度上的高度,求至少几个矩形可以拼出这个形状. 例如:给出的数组 H[0] = 8 H[1] = 8 H[2] = 5 H[3] = 7 H[4] = 9 ...

  4. codility上的问题(18) Rho 2012

    从正整数1开始,产生一个数列,数列中的每个数是之前出现过的任意两个数的和(可以相等),问产生正整数A,需要的数列长度至少是多少?返回这样一个最短的序列. 例如A=42 可以这样[1, 2, 3, 6, ...

  5. codility上的问题 (23)Chi 2012

    这个题也比较有意思.意思是给定一个数组A,长度为M,里面都是正整数,代表每块地形的高度.现在要测试一种加农炮,给定一个炮弹的高度H, 如果存在最小的I,满足0 < I <  M,满足A[I ...

  6. Codility上的问题 (16) Omicron 2012

    比较无聊的题,求斐波那契数的第N^M项. f(0) = 0, f(1) = 1, f(n) = f(n - 1) + f(n - 2),结果对10000103取模. N, M在[0..10^7]之间. ...

  7. Codility上的问题 (17) PI 2012

    这个题比较简单,给定一个整数数组,对每个元素,求出和它最近比它大的数的距离(下标绝对值),如果没有比它大的数,认为距离是0. 数组元素个数 N [0..50000],数组元素范围[-10^9, +10 ...

  8. codility上的练习(5)

    codility出了lesson 5了. (1) 合法括号序列,包括( [ { ) ] }这6种字符的字符串,长度N在[0..200000]范围内,为其是否合法. 要求时间复杂度O(N),空间复杂度O ...

  9. codility上的问题(34) Fluorum 2014

    好久没写codility的题了.一来没时间,二来有的题目不太好分析.这个题比較有意思,我还没有给出很严格的证明.

随机推荐

  1. java集合经常出现空指针问题的解决方案

    我自己问自己这个问题的时候都把自己给雷住了,但是现实如此,经常写的程序就是出现空指针的错误. 如: public List add(){ List list=null; try { list=new ...

  2. bzoj4034

    http://www.lydsy.com/JudgeOnline/problem.php?id=4034 树链剖分. 跟NOI2015的“软件包管理”一模一样..... 河南的爽死了...... #i ...

  3. struct2(四)编写Struct2 的Action

    简介: 1.映射一个Action到一个类上面 2.把结果返回到view展示 3.编写Action对应的控制逻辑   1. Action Mapping <action name="he ...

  4. 解决Jenkins上git出现的“ERROR: Error fetching remote repo 'origin'”问题

    今天对清掉了Jenkins中项目的工作空间,结果构建出现“ERROR: Error fetching remote repo 'origin'”问题:网上各种找也没找到解决这个问题的方法. 后来看错误 ...

  5. WebView使用

    WebView是View的一个子类,可以让你在activity中显示网页. 可以在布局文件中写入WebView:比如下面这个写了一个填满整个屏幕的WebView: <?xml version=& ...

  6. hdu4126Genghis Khan the ConquerorGenghis Khan the Conqueror(MST+树形DP)

    题目请戳这里 题目大意:给n个点,m条边,每条边权值c,现在要使这n个点连通.现在已知某条边要发生突变,再给q个三元组,每个三元组(a,b,c),(a,b)表示图中可能发生突变的边,该边一定是图中的边 ...

  7. 关于SVN版本控制器的问题与解决方法

    1.SVN Working copy is too old 有个.svn的文件夹,去掉在commit试试! 2.中文字符变乱码 尽量不要用中文命名文件,因为很多软件对中文的支持还是有不好的地方.

  8. ASE中的主要数据库

    Adaptive Server包括多种类型数据库: 必需数据库. “附加功能”数据库 .例子数据库 .应用数据库 1.必需数据库 master 数据库包含系统表,这些系统表中存储的数据被用来管理,有 ...

  9. mysql连接提示1030

    今天上午,开发使用工具连上mysql,连接一个库,就提示 mysql 错误 ERROR 1030 Got error 28 from. 查询资料,说可能是磁盘空间不足.果然连上去一看/分区空间只有数十 ...

  10. Activity-在ListFragment中为ListView增加空白视图

     有两种方法可以实现为ListView添加空白视图.但是原理都一样: 第一种方法是XML+代码添加: 1.定义emptyView视图 2.调用AdapterView的setEmptyView(empt ...