java-代码随想录第48天|739. 每日温度、496.下一个更大元素 I、503.下一个更大元素II
目录
单调栈
739. 每日温度
496.下一个更大元素 I
503.下一个更大元素II
学习链接:代码随想录
单调栈
1.单调栈的任务
求一个元素,左边或者右边第一个比当前元素大或者小得元素,找到这个元素对应得数值或者下标
2.单调栈
栈里面得元素保证递增或者递减得
3.单调栈存什么?
元素得下标
4.递增还是递减?
递增:当前这个元素后面第一个比他大得元素得位置
递减:当前这个元素后面第一个比他小得元素得位置
5.单调栈在题目种得作用?
记录之前已经遍历过得元素,然后和当前元素做一个对比
6.使用单调栈主要有三个判断条件。
当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
739. 每日温度
链接:739. 每日温度 - 力扣(LeetCode)
题目:
给定一个整数数组
temperatures
,表示每天的温度,返回一个数组answer
,其中answer[i]
是指对于第i
天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用0
来代替。
题解:
当前遍历的元素T[i]小于栈顶元素T[st.top()],入栈
当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况,入栈
当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况,result[st.top()]=i-st.top(),弹出栈顶元素
class Solution {// 版本 1public int[] dailyTemperatures(int[] temperatures) {int lens=temperatures.length;int []res=new int[lens];/**如果当前遍历的元素 大于栈顶元素,表示 栈顶元素的 右边的最大的元素就是 当前遍历的元素,所以弹出 栈顶元素,并记录如果栈不空的话,还要考虑新的栈顶与当前元素的大小关系否则的话,可以直接入栈。注意,单调栈里 加入的元素是 下标。*/Deque<Integer> stack=new LinkedList<>();stack.push(0);for(int i=1;i<lens;i++){if(temperatures[i]<=temperatures[stack.peek()]){stack.push(i);}else{while(!stack.isEmpty()&&temperatures[i]>temperatures[stack.peek()]){res[stack.peek()]=i-stack.peek();stack.pop();}stack.push(i);}}return res;}
496.下一个更大元素 I
链接:496. 下一个更大元素 I - 力扣(LeetCode)
题目:
nums1
中数字x
的 下一个更大元素 是指x
在nums2
中对应位置 右侧 的 第一个 比x
大的元素。给你两个 没有重复元素 的数组
nums1
和nums2
,下标从 0 开始计数,其中nums1
是nums2
的子集。对于每个
0 <= i < nums1.length
,找出满足nums1[i] == nums2[j]
的下标j
,并且在nums2
确定nums2[j]
的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是-1
。返回一个长度为
nums1.length
的数组ans
作为答案,满足ans[i]
是如上所述的 下一个更大元素 。
题解:
用hashmap对第一个数组进行映射
对第二个数组,通过单调栈求第一个比当前元素大得值
根据映射判断nums1中是否包含nums2中得值
如果包含则将nums1对应位置赋值为nums2中第一个比当前元素大得值
class Solution {public int[] nextGreaterElement(int[] nums1, int[] nums2) {//单调栈Stack<Integer> temp = new Stack<>();//结果数组int[] res = new int[nums1.length];//初始化为-1Arrays.fill(res,-1);//对nums1做映射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]) {//判断栈顶元素是否 出现在数组1中,if (hashMap.containsKey(nums2[temp.peek()])){//得到栈顶元素在数组1中得下标Integer index = hashMap.get(nums2[temp.peek()]);//给结果数组进行赋值res[index] = nums2[i];}temp.pop();}temp.add(i);}}return res;}
}
503.下一个更大元素II
链接:503. 下一个更大元素 II - 力扣(LeetCode)
题目:
给定一个循环数组
nums
(nums[nums.length - 1]
的下一个元素是nums[0]
),返回nums
中每个元素的 下一个更大元素 。数字
x
的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出-1
。
题解:
环形:用%模拟两个数组得拼接操作
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];//默认全部初始化为-1Arrays.fill(result,-1);//栈中存放的是nums中的元素下标Stack<Integer> st= new Stack<>();for(int i = 0; i < 2*size; i++) {while(!st.empty() && nums[i % size] > nums[st.peek()]) {//更新resultresult[st.peek()] = nums[i % size];//弹出栈顶st.pop();}st.push(i % size);}return result;}
}