LeetCode C++11-下一个更大元素II

题目描述

       给定一个循环数组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 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值