单调栈以前从来没接触过。要点有几个:
- 单调栈要想好自顶到底是递增还是递减,在本题要求的是右边的较大值,所以设置为从顶到底递增。
- 在本题,单调栈里存放的是数组的下标
- 情形有三种: 当前元素大于顶,小于顶,等于顶。
- 小于等于顶时,符合递增规律,进栈
- 大于顶时,要持续pop直至当前元素小于等于顶。同时每一步要记录结果。
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
Deque<Integer> stk = new LinkedList<Integer>();
int len = temperatures.length;
int[] res = new int[len];
stk.push(0);
for(int i=1; i<len; i++) {
int top = temperatures[stk.peek()];
if(temperatures[i] <= top) {
stk.push(i);
}
else {
while(!stk.isEmpty() && temperatures[stk.peek()] < temperatures[i]) {
res[stk.peek()] = i - stk.peek();
stk.pop();
}
stk.push(i);
}
}
return res;
}
}
这题跟上一题类似,但加了个子数组,所以更绕了一些。 要注意题目提到没有重复元素,所以可以用map来保存数组元素和下标的组合,方便查找。另外,相等的情况可以不考虑了。 单调栈同样为递增。 要注意初始化为-1,因为有些数组2的元素,在数组1中不存在。
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
HashMap<Integer, Integer> mmap = new HashMap<>();
for(int i=0; i<len1; i++) {
mmap.put(nums1[i], i);
}
Deque<Integer> stk = new LinkedList<Integer>();
int[] res = new int[len1];
Arrays.fill(res, -1);
stk.push(0);
for(int i=1; i<len2; i++) {
if(nums2[stk.peek()] >= nums2[i]) {
stk.push(i);
}
else {
while(!stk.isEmpty() && nums2[stk.peek()] < nums2[i]) {
int cur = nums2[stk.peek()];
if(mmap.containsKey(cur)) {
Integer idx1 = mmap.get(cur);
res[idx1] = nums2[i];
}
stk.pop();
}
stk.push(i);
}
}
return res;
}
}