1.题目描述

给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。

示例 1:

输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。

注意: 输入数组的长度不会超过 10000。

2.解法一:暴力法

思路:对于nums中每个元素,直接遍历两遍,确定下一个更大的数存在与否。

代码:运行时间296 ms

class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n = nums.size();
if(n==) return {}; vector<int> res(n,-);
for(int i=; i<n; ++i){
//下一个更大的数
for(int j=i+; j<*n; ++j){
int num2 = nums[j%n];
if(nums[i] < num2){
res[i]=num2;
break;}
}
}
return res;
}
};

3.解法二:翻倍数组,避免循环(栈)

思路:将原nums数组增长一倍,把nums完整拷贝到增长的区间。因为只需要遍历数组两遍,一定可以确定nums中的每一个元素的下一个更大的数,存在或不存在。

代码:运行时间 144ms

class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
//小技巧:增大一倍数组,不用考虑循环
for(int num : nums){
doubleNums.push_back(num);
}
for(int num : nums){
doubleNums.push_back(num);
} int sz = nums.size();
vector<int> res(sz,-);//sz在运行时才有正确值,所以这两个定义放在函数内部
for(int i=; i<*sz ; ++i){
while(!st.empty() && nums[st.top()]<doubleNums[i]){
res[st.top()]=doubleNums[i];
st.pop();
}
if(i<sz) st.push(i);//只需要原nums中的数字所处位置的【下标】进栈
//因为res的长度必须是sz,超过sz的部分我们只是为了给之前栈中的数字找较大值,所以不能压入栈
}
return res;
}
private:
vector<int> doubleNums;
stack<int> st;
};

4.解法三:取模运算,循环遍历(栈)

思路:基本同理于解法一,数组需要遍历两次(循环遍历),才能确定每一个元素的下一个更大的数字是否存在。这里的改进在于:无需把nums增长一倍并拷贝,而是通过取模运算( i = i % sz),使得遍历的下标 i 不越界。显然,这样更简单。

代码:运行时间96ms

class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n = nums.size();
vector<int> res(n, -);//技巧:提前都初始化为-1,减少后面重新赋值的步骤 for (int i = ; i < * n; ++i) {
int num = nums[i % n];
while (!st.empty() && nums[st.top()] < num) {
res[st.top()] = num; st.pop();
}
if (i < n) st.push(i);//下标进栈
}
return res;
}
private:
stack<int> st;
};

5.解法四:启发性思路,定义struct元素入栈比较

思路:

  • 定义struct  Item { int index; int v;} ,为的就是协调对应数组元素值与数组下标的关系,便于比较。
  • 上面的解法二和三中的采用的是下标进栈,达到和这里使用struct一样的效果。

代码:运行时间148ms

struct Item {
int index;
int v;
}; class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n=nums.size();
if(n==) return {}; vector<int> res(n,-);
stack<Item> s;
Item t;
t.index=;
t.v=nums[];
s.push(t);
//遍历第一次
for(int i=;i<n;++i) {
while(!s.empty() && nums[i]>(s.top()).v) {
res[(s.top()).index]=nums[i];
s.pop();
}
t.index=i;
t.v=nums[i];
s.push(t);
}
//遍历第二次
for(int i=;i<n;++i) {
if(s.empty())
break;
while(!s.empty() && nums[i]>(s.top()).v) {
res[(s.top()).index]=nums[i];
s.pop();
}
}
return res;
}
};

参考资料:

1.[LeetCode] Next Greater Element II 下一个较大的元素之二

Leetcode 503. 下一个更大元素 II的更多相关文章

  1. LeetCode 503. 下一个更大元素 II(Next Greater Element II)

    503. 下一个更大元素 II 503. Next Greater Element II 题目描述 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 ...

  2. Java实现 LeetCode 503 下一个更大元素 II

    503. 下一个更大元素 II 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大 ...

  3. 503. 下一个更大元素 II

    503. 下一个更大元素 II 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大 ...

  4. Leetcode 503.下一个更大元素

    下一个更大元素 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你 ...

  5. LeetCode 556. 下一个更大元素 III(Next Greater Element III)

    556. 下一个更大元素 III 556. Next Greater Element III 题目描述 给定一个 32 位正整数 n,你需要找到最小的 32 位整数,其与 n 中存在的位数完全相同,并 ...

  6. LeetCode 496. 下一个更大元素 I(Next Greater Element I) 35

    496. 下一个更大元素 I 496. Next Greater Element I 题目描述 给定两个没有重复元素的数组 nums1 和 nums2,其中 nums1 是 nums2 的子集.找到  ...

  7. LeetCode:下一个更大元素I【31】

    LeetCode:下一个更大元素I[31] 题目描述 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的 ...

  8. 503 Next Greater Element II 下一个更大元素 II

    给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它 ...

  9. [Leetcode]下一个更大元素II

    题目 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地 ...

随机推荐

  1. BugPhobia回顾篇章:团队Alpha阶段工作分析

    0x00:序言 1 universe, 9 planets, 204 countries,809 islands, 7 seas, and i had the privilege to meet yo ...

  2. MathExam作业

    作业 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 50 40 • Estimate • ...

  3. 2018-2019-20172321 《Java软件结构与数据结构》第六周学习总结

    2018-2019-20172321 <Java软件结构与数据结构>第六周学习总结 教材学习内容总结 第10章 树 10.1概述 树由一个包含结点和边的集构成,其中的元素被储存在这些结点中 ...

  4. python learning Regular Expression.py

    # 正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式通常被用来检索.替换那些符合某个模式(规 ...

  5. 【CSAPP笔记】13. 链接

    下面就要进入本书的第二部分--在系统上运行程序.书的第一部分,主要是研究单个应用程序,关注的是数据类型.机器指令.程序性能.存储器系统等话题.在书的第二部分,我们继续对计算机系统的探索.现代操作系统与 ...

  6. 牛客网国庆集训派对Day3题目 2018年

    链接:https://www.nowcoder.com/acm/contest/203/D来源:牛客网 Shopping 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K ...

  7. 怎样利用好单片机上的存储器资源来实现OD的存储与访问

    转自:http://www.cnblogs.com/winshton/p/4897789.html 我们知道OD(对象字典)是CANopen的核心,所有功能都是围绕它开展的,是协议栈的数据中心,良好的 ...

  8. 0422数学口袋精灵bug发现

    团队成员的博客园地址: 蔡彩虹:http://home.cnblogs.com/u/caicaihong/ 曾治业:http://www.cnblogs.com/zzy999/ 蓝叶:http://w ...

  9. debug阶段贡献分

    组名: 新蜂 组长: 武志远 组员: 宫成荣 谢孝淼 杨柳 李峤 项目名称: java俄罗斯方块NEO 发布时间:11.29 武志远 武志远 武志远 武志远 武志远 宫成荣 宫成荣 杨柳 宫成荣 宫成 ...

  10. Selenium_IDE的基本使用及脚本解析

    Selenium确实还是很强大的.根据我以往的经验,这个东西在web测试里的作用还是相当大的.经过近期研究,暂时对基本运作方式有了一定了 解,依旧找个实例记录一下.本段脚本实现的是网易返现个人中心登录 ...