代码随想录刷题记录 day50 每日温度+下一个更大元素 I

代码随想录刷题记录 day50 每日温度+下一个更大元素 I

739. 每日温度

代码随想录刷题记录 day50 每日温度+下一个更大元素 I_第1张图片

思想

1.暴力解 两次for 超时了

2.单调栈

花了点时间理解的。

单调栈的基础入门题。找到一个数组中右边的第一个大于 等于 或者小于当前元素的下标的位置

以时间换空间,用一个栈来记录右边第一个比当前元素大的元素。只需要遍历一次就好了

栈里面存放的是元素的下标。需要处理以下三种情况

  1. 当前遍历的元素temperatures[i]小于栈顶元素temperatures[st.top()]的情况
  2. 当前遍历的元素temperatures[i]等于栈顶元素temperatures[st.top()]的情况
  3. 当前遍历的元素temperatures[i]大于栈顶元素temperatures[st.top()]的情况

因为本题是要找到大于的元素,所以对于1.2两种情况 直接将元素的下标插入到栈中就好了。

对于找到了右边第一个大于的元素,则进行以下的处理。

stack.peek() 记录着的是栈顶元素的下标

i-stack.peek()表示当前的这个元素和栈顶所记录的元素的距离

res[stack.peek()] 赋值

出栈

while()表示对当前栈内元素 所有小于temperatures[i]的值就要记录距离并出栈

最终将当前的元素入栈

//大于栈顶对应的元素
                //把所有小于的都弹出 同时记录数值
                while(!stack.empty() && temperatures[i]>temperatures[stack.peek()]){
                    res[stack.peek()]=i-stack.peek();
                    stack.pop();
                }
                stack.push(i);
代码
class Solution {
    // public int[] dailyTemperatures(int[] temperatures) {
    //     int [] ans=new int[temperatures.length];
    // 暴力解
    //     for(int i=0;i
    //         for(int j=i+1;j
    //             if(temperatures[j]>temperatures[i]){
    //                 ans[i]=j-i;
    //                 break;//跳出当前一层的循环
    //             }
    //         }
    //     }
    //     return ans;
    // }

    public int[] dailyTemperatures(int[] temperatures) {
        //单调栈 单调栈里存放元素的下标
        Stack<Integer> stack=new Stack<>();
        stack.push(0);
        int [] res=new int[temperatures.length];

        for(int i=1;i<temperatures.length;i++){
            if(temperatures[i]<temperatures[stack.peek()] ){
                //小于栈顶元素 直接入栈
                stack.push(i);
            }else if(temperatures[i]==temperatures[stack.peek()]){
                //等于也是直接入栈
                stack.push(i);
            }else{
                //大于栈顶对应的元素
                //把所有小于的都弹出 同时记录数值
                while(!stack.empty() && temperatures[i]>temperatures[stack.peek()]){
                    res[stack.peek()]=i-stack.peek();
                    stack.pop();
                }
                stack.push(i);
            }
        }
        return res;
    }
}

496. 下一个更大元素 I

代码随想录刷题记录 day50 每日温度+下一个更大元素 I_第2张图片

思想

和前面一道题目的区别是这题目是两个数组,需要用一个hashmap来维护nums1的映射关系。

可以根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过

key: num1[i] value i

HashMap<Integer,Integer> hashMap=new HashMap<>();
        for(int i=0;i<nums1.length;i++){
            hashMap.put(nums1[i],i);
        }

栈中存放的是num1的下标

数组res来存放结果,根据题目要求 需要初始化为-1

讨论三种情况

  1. 当前遍历的元素nums2[i]小于栈顶元素nums2[stack.peek()]
  2. 当前遍历的元素nums2[i]等于栈顶元素nums2[stack.peek()]
  3. 当前遍历的元素nums2[i]大于于栈顶元素nums2[stack.peek()]

因为本题是找大于的 所以对于1.2两种,只要往栈里添加元素就好了。

考虑第三种情况,需要进行以下几个步骤

stack.peek() 栈顶元素,存放的是nums1的下标

nums2[stack.peek()] 获得具体元素的值

判断当前nums2的元素在nums1中是否出现过

出现过 index记录元素在nums1中的下标的位置

把元素弹出栈

				while(!stack.empty() && nums2[i]>nums2[stack.peek()]){
                    if(hashMap.containsKey(nums2[stack.peek()])){
                        int index=hashMap.get(nums2[stack.peek()]);
                        res[index]=nums2[i];
                    }
                    stack.pop();
                }
                stack.push(i);
代码
class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        //nums1 是nums2的子集  nums1中的值在nums2中都能找到
        Stack<Integer> stack=new Stack<>();
        int [] res=new int[nums1.length];
        Arrays.fill(res,-1);
        //用一个hashmap 来做映射 可以根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过
        HashMap<Integer,Integer> hashMap=new HashMap<>();
        for(int i=0;i<nums1.length;i++){
            hashMap.put(nums1[i],i);
        }
        System.out.println(hashMap);

        //单调递增栈中存放的是nums1的下标
        stack.push(0);

        for(int i=1;i<nums1.length;i++){
            if(nums2[i]<nums2[stack.peek()]){
                //小于栈顶元素
                stack.push(i);
            }
            else if(nums2[i]==nums2[stack.peek()]){
                stack.push(i);
            }
            else{
                //nums2 中的下一个元素比栈顶的元素大了 涉及到入栈和出栈的操作
                //只是这一题需要先找到nums1中是否含有当前栈顶元素对应的元素
                //如果有 则要记录结果
                //如果没有 则直接出栈就好了
                while(!stack.empty() && nums2[i]>nums2[stack.peek()]){
                    if(hashMap.containsKey(nums2[stack.peek()])){
                        int index=hashMap.get(nums2[stack.peek()]);
                        res[index]=nums2[i];
                    }
                    stack.pop();
                }
                stack.push(i);
            }
        }

        return res;
    }
}

参考:代码随想录

你可能感兴趣的:(代码随想录刷题记录,java,leetcode,算法)