leetcode 42.接雨水,leetcode 503. 下一个更大元素Ⅱ

“即使到不了远方,心中也要有远方的模样。”

1.leetcode 503. 下一个更大元素Ⅱ

在这里插入图片描述

1.1 详细思路及步骤

  这题基本上和昨天总结的两个题思路是一模一样的,区别不同的就是,这是一个循环数组,那就直接将两个数组链接就好了。昨天的–>点这里

1.2 java版代码示例
class Solution {
    public int[] nextGreaterElements(int[] nums) {
      int len=nums.length;
      int[] result=new int[len];
      if(nums == null || nums.length<=1)return new int[]{-1};
      Arrays.fill(result,-1);
      Deque<Integer> stack = new LinkedList<Integer>();//用Deque也能做单调栈
       // Stack<Integer> stack= new Stack<>();
    //   stack.push(0);
      for(int i=0;i<len*2-1;i++){
          while(!stack.isEmpty()&&(nums[i%len]>nums[stack.peek()])){
            result[stack.pop()]=nums[i%len];
          }
          stack.push(i%len);
    }
    return result;
}
}

2.leetcode 42.接雨水

在这里插入图片描述

2.1 详细思路及步骤

  这题首先拿着可能不好分析,那么就先光看局部,从局部分析,判断i位置能接的雨水就找到i位置右边和左边的最大值,然后比较这俩最大值的最小值,也就是i位置能装的水就是Math.min(left_max,right_max)-height[i]

然后先看暴力解法

class Solution {
    public int trap(int[] height) {
       int len=height.length;
       int res=0;
       for(int i=0;i<len;i++){
           int l_max=0,r_max=0;
           //求i右边的最大值
           for(int j=i;j<len;j++){
               l_max=Math.max(l_max,height[j]);
           }
           //求i左边的最大值
           for(int j=i;j>=0;j--){
               r_max=Math.max(r_max,height[j]);
           }
           res+=Math.min(l_max,r_max)-height[i];
       }  
       return res;
    }
}

  根据暴力解法继续优化,上面的每次遍历i都会将i左边和右边的最大值遍历出来,其实也可以先将这俩遍历存储到数组中,然后直接用。

优化过程

class Solution {
    public int trap(int[] height) {
    if (height.length == 0) {
        return 0;
    }
    int n = height.length;
    int res = 0;
    // 数组充当备忘录
    int[] l_max = new int[n];
    int[] r_max = new int[n];
    // 初始化 base case
    l_max[0] = height[0];
    r_max[n - 1] = height[n - 1];
    // 从左向右计算 l_max
    for (int i = 1; i < n; i++)
        l_max[i] = Math.max(height[i], l_max[i - 1]);
    // 从右向左计算 r_max
    for (int i = n - 2; i >= 0; i--)
        r_max[i] = Math.max(height[i], r_max[i + 1]);
    // 计算答案
    for (int i = 1; i < n - 1; i++)
        res += Math.min(l_max[i], r_max[i]) - height[i];
    return res;
    }
}

  还有一种更优的解法就是双指针解法,思路基本上和上面一样,边遍历边找最大值,代码放下面。

2.2 java版代码示例
class Solution {
    public int trap(int[] height) {
    if (height.length == 0) {
        return 0;
    }
    //int n = height.length;
    int res = 0;
    int l_max=0,r_max=0;
    int left=0,right=height.length-1;
   while(left<right){
       l_max=Math.max(l_max,height[left]);
       r_max=Math.max(r_max,height[right]);
       if(l_max<r_max){
           res+=l_max-height[left];
           left++;
       }else{
           res+=r_max-height[right];
           right--;
       }
   }
    return res;
    }
}
  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值