下一个更大的元素

Next Greater Element

本文关键字:元素 下一个      更新时间:2023-10-16
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
stack<int>s;
stack<int>q;
for (int i = n - 1; i > 0; i--)
{
s.push(arr[i]);
}
while (!s.empty())
{
int a = s.top();
s.pop();
int flag = 0;
while (!s.empty())
{
int p = s.top();
if (a >= p)
{
q.push(p);
s.pop();
}
else {
cout << p;
flag = 1;
break;
}
p = s.top();
}
if (flag == 0)
{
cout << -1;
}
while (!q.empty())
{
s.push(q.top());
q.pop();
}
}
}
return 0;
}

给定一个数组,为每个元素打印下一个更大的元素 (NGE)。元素 x 的下一个较大元素是数组中 x 右侧的第一个较大元素。对于不存在更大元素的元素,将下一个更大的元素视为 -1。 为什么此代码会出现分段错误?

更改以下内容:

for (int i = n - 1; i > 0; i--)

对此:

for (int i = n - 1; i >= 0; i--)

因为您想将所有元素推送到堆栈。

之后,对于此输入:

1
3
1
2
3

我得到了预期的输出:

23-1

注意:正如@John所说,p = s.top();什么都不做,因此可以安全地将其删除(因为无论如何p都会超出范围)。

p=s.top();

我怀疑在这里崩溃。不能保证此时s不为空。

代码行没有任何影响(除了可能使程序崩溃),因为p是一个即将超出范围的局部变量。它可以安全地移除。

在解决了我上一个答案中的问题后,可以根据@VladFromMoscow的评论,并使用循环来实现这一点,而无需使用两个额外的数据结构。

策略可能如下:

For every element `e` in the array
Check if next element of `e` is greater than `e`
If yes, print it

这意味着使用两个 for 循环,其中第一个循环将扫描整个数组。第二个循环将从e的下一个元素扫描数组,直到数组的末尾。

注意:您可以跳过第一个循环中的最后一个元素,因为它保证没有任何下一个元素(因此也没有更大的下一个元素)。

但是,您可能需要存储这些更大的元素,并且肯定可以使用堆栈(LIFO数据结构),但是我发现使用FIFO数据结构(例如队列)更自然。当然,也可以使用数组。

请注意,即使需要存储元素,使用这种基于循环的方法,也可以使用一个额外的数据结构,而不是两个(如在代码中一样)。

例:

#include <iostream>
#include <queue>
using namespace std;
int main(void)
{
int n;
cin >> n;
if(!n)
{
cout << "Array will be empty, exiting..n";
return 1;
}
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
queue<int> q;
// start 1st element until pre-last.
for(int i = 0; i < n - 1; ++i)
{
// start from next element of i-th element, until last.
for(int j = i + 1; j < n; ++j)
{
if(arr[j] > arr[i])
{
q.push(arr[j]);
break;
}
}
}
while(!q.empty())
{
cout << q.front() << ", ";
q.pop();
}
// last element of array does not have any next element
cout << "-1n";
return 0;
}

输入:

3

1 2 3

输出:

2, 3, -1

注意:如果您不需要存储下一个更大的元素,则只需打印arr[j]而不是执行q.push(arr[j]);,然后break循环。

Python 中的解决方案

a = [1, 5, 2, 9]
a.reverse()
if a == sorted(a):
print("No")
else:
for i in range(len(a)-1):
if a[i] > a[i+1]:
a[i], a[i+1] = a[i+1], a[i]
break
a.reverse()
print(a)

输出 :[1, 5, 9, 2]

#include <bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int test;
cin >> test;
while(test--)
{
int n;
cin >> n ;
vector<int>v(n);
for(int i=0;i<n;i++)
cin >> v[i];
vector<int>output(n,-1);
stack<int>s;
s.push(0);
for(int i=0;i<n;i++)
{
while(!s.empty() && v[s.top()]<v[i])
{
output[s.top()]=v[i];
s.pop();
}
s.push(i);
}
for(auto x:output)
cout << x << " ";
cout << "n";
}
return 0;
} 
<小时 />

样本输入: 1 4 4 5 2 25 示例输出: 5 25 25 -1