下一个更大元素1

下一个更大元素1(难度:简单)

题目
方法
code

图解

图解

另一种写法(从后往前)

转自:

作者:labuladong 链接:https://leetcode-cn.com/problems/next-greater-element-i/solution/dan-diao-zhan-jie-jue-next-greater-number-yi-lei-w/ 来源:力扣(LeetCode)

1

模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
vector<int> nextGreaterElement(vector<int>& nums) {
vector<int> ans(nums.size()); // 存放答案的数组
stack<int> s;
for (int i = nums.size() - 1; i >= 0; i--) { // 倒着往栈里放
while (!s.empty() && s.top() <= nums[i]) { // 判定个子高矮
s.pop(); // 矮个起开,反正也被挡着了。。。
}
ans[i] = s.empty() ? -1 : s.top(); // 这个元素身后的第一个高个
s.push(nums[i]); // 进队,接受之后的身高判定吧!
}
return ans;
}

for 循环要从后往前扫描元素,因为我们借助的是栈的结构,倒着入栈,其实是正着出栈。while 循环是把两个“高个”元素之间的元素排除,因为他们的存在没有意义,前面挡着个“更高”的元素,所以他们不可能被作为后续进来的元素的 Next Great Number 了。

这个算法的时间复杂度不是那么直观,如果你看到 for 循环嵌套 while 循环,可能认为这个算法的复杂度也是 O(n^2),但是实际上这个算法的复杂度只有 O(n)。

分析它的时间复杂度,要从整体来看:总共有 n 个元素,每个元素都被 push 入栈了一次,而最多会被 pop 一次,没有任何冗余操作。所以总的计算规模是和元素规模 n 成正比的,也就是 O(n) 的复杂度。

本题代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
Stack<Integer> stack = new Stack<>();
Map<Integer, Integer> map = new HashMap<>();
int[] res = new int[nums1.length];

for(int i = nums2.length-1; i >= 0; i--){ // 倒着往栈里放
while(!stack.empty() && nums2[i]>=stack.peek()){
stack.pop();
}
map.put(nums2[i],stack.empty()?-1:stack.peek());
stack.push(nums2[i]);
}

for(int i=0; i<nums1.length; i++)
res[i] = map.get(nums1[i]);

return res;
}
}