最近做到一道题,非常有意思。一开始没能理解透,理解以后发现真的非常巧妙。
先给大家介绍一个概念,单调递增(单调递减)栈。此处参考AlphaINF的博客。
有了这个概念后,再来看一道题。
现在我们有一个int数组,请你找出数组中每个元素的下一个比它大的元素。
给定一个int数组A及数组的大小n,请返回一个int数组,代表每个元素比他大的下一个元素,若不存在则为-1。保证数组中元素均为正整数。
例如给定 [11,13,10,5,12,21,3], 7
返回:[13,21,12,12,21,-1,-1]
以第i个元素为例。要求i之后的较大元素,其实与i之前的元素无关,只与i之后的元素有关。所以其实可以倒着看这个问题。从最后一个元素往前看。
在从后往前看的过程中维护一个递增栈,也就是说只记录从最后一位开始逐渐减小的元素。在这中间较小的元素都被忽略掉。
以11 13 10 5 12 21 3这个序列为例。
于是每次弹出当前元素后,取出栈顶元素就可以得到下一个较大的元素。
代码如下:
vector<int> findNext(vector<int> A, int n) { vector<int> result; if(n <= 0){ return result; }//if stack<int> stack; stack.push(-1); for(int i = n-1;i >= 0;--i){ int top = stack.top(); while(top != -1 && A[i] >= top){ stack.pop(); top = stack.top(); }//while result.insert(result.begin(),top); stack.push(A[i]); }//for return result; }
这种方法,就可以在O(N)的时间内完成。