力扣739,496,503(单调栈)
739.每日温度
基本思想:
1.单调栈里存放的元素是什么?
单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。
2.单调栈里元素是递增还是递减?
顺序为栈头到栈底
此题使用递增序列,只有递增的时候,加入一个元素i,
才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i。
具体实现:
代码:
class Solution { public int[] dailyTemperatures(int[] temperatures) { Stack<Integer> stack = new Stack<>(); int[] res = new int[temperatures.length]; for (int i = 0; i < temperatures.length; i++) { while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) { int preIndex = stack.pop(); res[preIndex] = i - preIndex; } stack.push(i); } return res; } }
496.下一个更大元素
基本思想:
单调栈
具体实现:
1.result数组如果某位置没有被赋值,就应该是是-1,所以result数组初始化为-1。
2.在遍历nums2的过程中,要判断nums2[i]是否在nums1中出现过,
因为最后是要根据nums1元素的下标来更新result数组。
3.题目中说是两个没有重复元素 的数组 nums1 和 nums2
用map来做映射了。根据数值快速找到下标,
还可以判断nums2[i]是否在nums1中出现过。
综上
Stack<Integer> temp = new Stack<>(); int[] res = new int[nums1.length]; Arrays.fill(res,-1); HashMap<Integer, Integer> hashMap = new HashMap<>(); for (int i = 0 ; i< nums1.length ; i++){ hashMap.put(nums1[i],i); }
4.分析三种情况
(情况1)当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
此时满足递增栈(栈头到栈底的顺序),所以直接入栈。
(情况2)当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
如果相等的话,依然直接入栈,因为要求的是右边第一个比自己大的元素,而不是大于等于
(情况3)当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
此时如果入栈就不满足递增栈了,这也是找到右边第一个比自己大的元素的时候。
代码:
class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Stack<Integer> temp = new Stack<>(); int[] res = new int[nums1.length]; Arrays.fill(res,-1); HashMap<Integer,Integer> hashMap = new HashMap<>(); for (int i = 0; i < nums1.length; i++) { hashMap.put(nums1[i],i); } temp.add(0); for (int i = 1; i < nums2.length; i++) { if (nums2[i] <= nums2[temp.peek()]) { temp.add(i); } else { while (!temp.isEmpty() && nums2[temp.peek()] < nums2[i]){ if (hashMap.containsKey(nums2[temp.peek()])){ Integer index = hashMap.get(nums2[temp.peek()]); res[index] = nums2[i]; } temp.pop(); } temp.add(i); } } return res; } }
503.下一个更大元素II
基本思想:
在遍历的过程中模拟走了两遍nums
具体实现:
[1,2,1] 长度为3,遍历时i范围为0-5(2*length)
i%length
(0,1,2,3,4,5)%3 = (0,1,2,0,1,2)
代码:
class Solution { public int[] nextGreaterElements(int[] nums) { if(nums == null || nums.length <= 1) { return new int[]{-1}; } int size = nums.length; int[] result = new int[size]; Arrays.fill(result,-1); Stack<Integer> st = new Stack<>(); for(int i = 0; i < 2*size; i++){ while(!st.empty() && nums[i % size] > nums[st.peek()]){ result[st.peek()] = nums[i % size]; st.pop(); } st.push(i % size); } return result; } }