这是一道亚马逊的面试题。给定一个数组,打印出每一个元素的下一个更大的元素( Next Greater Element,NGE ),就叫做NGE问题吧。
a) 任何数组,最右边的元素的NGE为-1。
b) 对于一个降序排序的数组,所有元素得到NGE为-1
c) 对于数组{4, 5, 2, 25}, NGE分别为 5,25,25,-1
d) 对于数组{13, 7, 6, 12}, NGE分别为 -1,12,12,-1
方法1----枚举
使用二重循环,分别遍历所有的元素,即可找到该元素的NGE。是否复杂度O(n^2).
方法2----使用栈
数据测试:
一个元素x的下一个更大的元素是指在x的右边第一个比该元素大的元素。如果没有更大的元素,则输出-1。
a) 任何数组,最右边的元素的NGE为-1。
b) 对于一个降序排序的数组,所有元素得到NGE为-1
c) 对于数组{4, 5, 2, 25}, NGE分别为 5,25,25,-1
d) 对于数组{13, 7, 6, 12}, NGE分别为 -1,12,12,-1
方法1----枚举
使用二重循环,分别遍历所有的元素,即可找到该元素的NGE。是否复杂度O(n^2).
方法2----使用栈
我们可以用栈来维护一个递减的序列,里面存储的数组左边未找到NGE的元素,初始时只包含第一个元素。我们可以假定栈顶就是最小的元素,因此可以用从栈顶top开始和后面的元素next比较。如果top<next则说明,找到了top的NGE,可以弹出栈。然后继续比较栈顶元素top和next,直到栈为空或 next <= top。然后把next加入栈,以便查找next的NGE。由于只有一次遍历,时间复杂度为O(n)。
代码如下:
#include <iostream>
#include <stack>
using namespace std;
void FindNGE(int arry[], int & len)
{
stack<int> s;
s.push(arry[0]);
int next, top;
for (int i = 1; i < len; i++)
{
top = s.top();
next = arry[i];
while (!s.empty() && top < next)
{
cout << top << "-->" << next << endl;
s.pop();
//继续判断栈顶
if (!s.empty())
top = s.top();
}
//将下一个元素入栈
s.push(next);
}
while (!s.empty())
{
cout << s.top() << "-->" << "-1" << endl;
s.pop();
}
}
int main()
{
int arry[] = { 11, 13, 10, 5, 12,21, 3 };
int n = sizeof(arry) / sizeof(int);
FindNGE(arry, n);
return 0;
}
数据测试:
题目来自: http://www.acmerblog.com/next-greater-element-5811.html