题目描述
给定一个循环数组nums,数组的大小为n,第n个元素的下一个元素为第一个元素,返回nums中每个元素的下一个更大元素。
数字x的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出-1。
举例
示例1: 输入: nums=[1, 2, 1] 输出: [2, -1, 2]
说明: 1的下一个元素是2;2没有下一个元素,为-1;
示例2:输入:nums=[1,2,3,4,3] 输出:[2,3,4, -1,4]
示例3: 输入:nums=[5,4,2,1,3] 输出:[-1, 5, 3, 3, 5]
解题方法: 采用单调栈。通常来说,我们获取一个数组中各个数字的下一个更大的数字,第一时间想到的是循环遍历这个数组中的每一个数字,然后去查找各个数字的下一个更大的元素。我们现在换一种思维习惯,就是在遍历这个数组中每一个数字的时候,判断下这个数字是否是前面已经遍历数字的下一个更大的元素【最重要的是思维转变】。
用一个跟数组大小一致的数组保存结果,结果数组各个元素初始化为-1。分两次遍历数组中的元素,每次遍历到一个元素,依次将当前栈中小于该元素的值弹出栈(也就是说stack里面从栈顶到栈底必然是单调递增的,因为栈中小于当前待压栈元素都弹出栈了),并将当前元素记录为栈顶元素的下一个更大值保存在结果中,并将当前元素的下标压入栈中。第二次遍历,主要是因为当前数组是一个循环数组,当前存在部分尚未找到更大值的元素(下标)还遗留在栈中,需要再遍历每一个遗留在栈中的左边的元素才能确定,这些栈中的元素(下标)是否存在下一个更大值。(这里为什么要将数字的下标保存到栈中呢,因为最终通过下标更新对应的结果数组,起到一个类似于map的作用)
代码
#include <iostream>
#include <vector>
#include <stack>
std::vector<int> get_next_greater_index(const std::vector<int>& nums) {
int n = nums.size();
std::vector<int> result(n, -1);//初始化为-1,-1表示没有更大的元素
std::stack<int> stk; // 用于保存尚未找到下一个更大元素的数字
//第一次遍历:把每一个数字右边的数字遍历一遍,遍历后找不到更大值的数字会停留在栈中
for (int i = 0; i < n; i++) {
while (!stk.empty() && nums[stk.top()] < nums[i]) { //如果nums[i]比栈顶元素大,则nums[i]是栈顶元素的下一个更大值
int idx = stk.top();
result[idx] = nums[i];
stk.pop();
}
stk.push(i);
}
//第二次遍历: 由于是循环数组,上一次遍历没有考虑每个数字左边是否右更大值
for (int i = 0; i < n; i++) {
while (!stk.empty() && nums[stk.top()] < nums[i]) {
int idx = stk.top();
result[idx] = nums[i];
stk.pop();
}
}
return result;
}
void print_result(const std::vector<int>&input,
const std::vector<int>&output) {
// input
std::cout << "input:";
for (auto value : input) {
std::cout << value << " " ;
}
std::cout << std::endl;
// output
std::cout << "output:";
for (auto value : output) {
std::cout << value << " " ;
}
std::cout << std::endl;
}
int main()
{
// case1: nums = [1,2,1] ==> [2,-1,2]
std::vector<int> nums = {1, 2, 1};
auto result = get_next_greater_index(nums);
print_result(nums, result);
// case2: nums = [1,2,3,4,3]==>[2,3,4,-1,4]
nums = {1, 2, 3, 4, 3};
result = get_next_greater_index(nums);
print_result(nums, result);
// case3: nums=[5,4,2,1,3]==>[-1,5,3,3,5]
nums = {5, 4, 2, 1, 3};
result = get_next_greater_index(nums);
print_result(nums, result);
return 0;
}
代码运行结果如下:
input:1 2 1
output:2 -1 2
input:1 2 3 4 3
output:2 3 4 -1 4
input:5 4 2 1 3
output:-1 5 3 3 5