leetcode-zgd-day59-503.下一个更大元素II/42.接雨水

76 阅读1分钟

503.下一个更大元素II

题目链接:503. 下一个更大元素 II - 力扣(Leetcode)

解题思路:

数组拼接法:

 class Solution {
     public int[] nextGreaterElements(int[] nums) {
         Stack<Integer> stk = new Stack<>();
         int[] nums1 = Arrays.copyOf(nums, 2 * nums.length);
         for(int i = nums.length; i < nums1.length; i++){
             nums1[i] = nums1[i - nums.length];
         }
         int[] ans = new int[nums1.length];
         Arrays.fill(ans, -1);
         for (int i = 0; i < nums1.length; i++) {
             while(!stk.empty() && nums1[i] > nums1[stk.peek()]){
                 ans[stk.peek()] = nums1[i];
                 stk.pop();
             }
             stk.push(i);
         }
         return Arrays.copyOf(ans, nums.length);
     }
 }

未出栈元素单独处理法:

 class Solution {
     public int[] nextGreaterElements(int[] nums) {
         /**
          解题思路:
          该题在向后寻找的更大元素的基础之上,又增加了额外的条件
          如果后面没有,就从头再找,看是否可以找到
          */
         int[] ans = new int[nums.length];
         Arrays.fill(ans,-1);
         Stack<Integer> stk = new Stack<>();
         for(int i = 0; i < nums.length; i++){
             while(!stk.empty() && nums[stk.peek()] < nums[i]){
                 ans[stk.peek()] = nums[i];
                 stk.pop();
             }
             stk.push(i);
         }
         while(!stk.empty()){
             int i = stk.peek();
             for(int j = 0; j < i; j++){
                 if(nums[j] > nums[i]){
                     ans[i] = nums[j];
                     break;
                 }
             }
             stk.pop();
         }
 ​
         return ans;
     }
 }

取模不扩容法:

 class Solution {
     public int[] nextGreaterElements(int[] nums) {
         Stack<Integer> stk = new Stack<>();
         int[] ans = new int[nums.length];
         Arrays.fill(ans, -1);
         for (int i = 0; i < 2 * nums.length; i++) {
             while(!stk.empty() && nums[i % nums.length] > nums[stk.peek()]){
                 ans[stk.peek()] = nums[i % nums.length];
                 stk.pop();
             }
             stk.push(i % nums.length);
         }
         return ans;
     }
 }

42.接雨水

题目链接:42. 接雨水 - 力扣(Leetcode)

解题思路:

单调栈内是保持一个从栈头到栈底递增的一个关系,例如 5 4 2 这种

如果新过来的下标对应的障碍物高度高于栈顶元素,那么就代表着产生了水坑,例如 5 4 2 又新过来一个3。

3大于2,同时2又小于4,所以就产生了一个水坑。每产生一个水坑我们就计算这个水坑对应的深度。

 class Solution {
     public int trap(int[] height) {
         Stack<Integer> stk = new Stack<>();
         stk.push(0);
         int ans = 0;
         for(int i = 1; i < height.length; i++){
             if(height[i] < height[stk.peek()]){
                 stk.push(i);
             }else if(height[i] == height[stk.peek()]){
                 stk.pop();
                 stk.push(i);
             }else{
                 while(!stk.empty() && height[i] > height[stk.peek()]){
                     // 栈里本来就是递减的,外面来了一个大的元素,形成了水坑
                     int mid = stk.pop();
                     if(!stk.empty()){
                         int h = Math.min(height[stk.peek()], height[i]) - height[mid];
                         int w = i - stk.peek() - 1;
                         ans += h * w;
                     }
                 }
                 stk.push(i);
             }
         }
         return ans;
     }
 }