Leetcode 503. 下一个更大元素 II
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的更多相关文章
- LeetCode 503. 下一个更大元素 II(Next Greater Element II)
503. 下一个更大元素 II 503. Next Greater Element II 题目描述 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 ...
- Java实现 LeetCode 503 下一个更大元素 II
503. 下一个更大元素 II 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大 ...
- 503. 下一个更大元素 II
503. 下一个更大元素 II 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大 ...
- Leetcode 503.下一个更大元素
下一个更大元素 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你 ...
- LeetCode 556. 下一个更大元素 III(Next Greater Element III)
556. 下一个更大元素 III 556. Next Greater Element III 题目描述 给定一个 32 位正整数 n,你需要找到最小的 32 位整数,其与 n 中存在的位数完全相同,并 ...
- LeetCode 496. 下一个更大元素 I(Next Greater Element I) 35
496. 下一个更大元素 I 496. Next Greater Element I 题目描述 给定两个没有重复元素的数组 nums1 和 nums2,其中 nums1 是 nums2 的子集.找到 ...
- LeetCode:下一个更大元素I【31】
LeetCode:下一个更大元素I[31] 题目描述 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的 ...
- 503 Next Greater Element II 下一个更大元素 II
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它 ...
- [Leetcode]下一个更大元素II
题目 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地 ...
随机推荐
- Spring Bean注册解析(二)
在上文Spring Bean注册解析(一)中,我们讲解了Spring在注册Bean之前进行了哪些前期工作,以及Spring是如何存储注册的Bean的,并且详细介绍了Spring是如何解析 ...
- 第一个spring冲刺团队贡献分(80分满分)
团队贡献分(80分满分): 李泳江 24 叶煜稳 26 谢洪跃 18 周伟雄 12
- 第一次spring冲刺第5天
今天进行讨论基础功能的核心代码方面,还有简单的讨论继续关于界面的美化, 计算生成的答案功能 public class Core {// char[]h={'+','-','*','/'};int re ...
- 404 Note Found团队-项目UML设计
目录 团队信息 分工选择 课上分工 课下分工 ToDolist alpha版本要做的事情 燃尽图 UML 用例图 状态图 活动图 类图 部署图 实例图 对象图 时序图 包图 通信图 贡献分评定 课上贡 ...
- js如何判断一个值是不是Array类型
本来判断一个对象类型用typeof是最好的,不过对于Array类型是不适用的可以使用 instanceof操作符var arrayStr=new Array("1","2 ...
- ASP.NET MVC 1.0 参考源码索引
http://www.projky.com/asp.netmvc/1.0/System/Web/Mvc/AcceptVerbsAttribute.cs.htmlhttp://www.projky.co ...
- testNg-build.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <proje ...
- Handler,Looper,HandlerThread浅析
Handler想必在大家写Android代码过程中已经运用得炉火纯青,特别是在做阻塞操作线程到UI线程的更新上.Handler用得恰当,能防止很多多线程异常. 而Looper大家也肯定有接触过,只不过 ...
- BZOJ5286 HNOI/AHOI2018转盘(分块/线段树)
显然最优走法是先一直停在初始位置然后一次性走完一圈.将序列倍长后,相当于找一个长度为n的区间[l,l+n),使其中ti+l+n-1-i的最大值最小.容易发现ti-i>ti+n-(i+n),所以也 ...
- VM ware 中win2008 找不到网卡驱动的解决办法之一
在.vmx文件中用如下语句指定: ethernet0.virtualDev = "e1000" 其值为e1000指定网卡类型为Intel(R) PRO/1000(6.5默认为此项) ...