代码随想录|503.下一个更大元素II,42.接雨水(大厂面试经典)

503.下一个更大元素II

本题跟题目739类似,唯一不同的是要记录的是下一个更大元素了,而不是下标,而且添加了循环数组

本题将单调栈与循环数组结合起来,可以把数组看成是原来的两倍相当于模拟循环

代码实现 

class Solution {
    public int[] nextGreaterElements(int[] nums) {

         int[] res=new int[nums.length];
        Deque stack=new LinkedList<>();
        int m=nums.length;
        Arrays.fill(res,-1);
        stack.push(0);
        //记住单调栈存放的是元素的下标
        for(int i=1;i<2*m;i++){
            if(nums[i%m]<=nums[stack.peek()]){//当前遍历的元素小于等于栈顶元素,直接把下标入栈
               stack.push(i%m);
            }
            else{
                while(!stack.isEmpty()&&nums[i%m]>nums[stack.peek()]){
                    res[stack.peek()]=nums[i%m];
                    stack.pop();
                } 
                stack.push(i%m);
            }
        }
        return res;


    }
}

42.接雨水(大厂面试经典)

双指针解法,

求出每一列可以接收多少雨水,第一列和最后一列无法接收雨水,

class Solution {
    public int trap(int[] height) {
        int n=height.length;
        int rain=0;
        
        for(int i=0;i=0;j--){

                //求该列左边最高
                if(height[j]>lheight){lheight=height[j];}
            }
            for(int j=i+1;jrheight){rheight=height[j];}//小细节这里要height[j]>rheight而不是height[j]height[i]


            }
            int h=Math.min(lheight,rheight)-height[i];

           // System.out.println(h);
            if(h>0){//小细节,h>0
                rain+=h;

            }
           
        }
        return rain;
    }
}
//单调栈解法

单调栈解法

单调栈从栈头到栈底应该是从小到大的顺序(我们在栈头弹出元素),因为我们要接雨水需要形成一个凹槽,分为三种情况考虑:

1.如果当前元素小于栈头元素,那么直接push当前元素;

2.如果当前元素等于栈头元素,那么我们先pop栈头元素再push当前元素;

3.如果当前元素大于栈头元素,我们先计算能接到的雨水体积再push当前元素

代码实现

class Solution {
    public int trap(int[] height) {
        Stack stack=new Stack<>();
        if(height.length<=2){return 0;}
        stack.push(0);
        int result=0;
        for(int i=1;iheight[stack.peek()])){
                int mid=stack.pop();
                if(!stack.isEmpty()){//不加这个条件判断会出现java.util.EmptyStackException
                int left=stack.peek();//这里是peek而不是pop
                int myHeight=Math.min(height[i],height[left])-height[mid];
                int width=i-left-1;
                int sum=myHeight*width;
                if(sum>0){
                    result+=sum;//计算的是从left-i这个范围的接水体积

                }
              
                }

            }
                stack.push(i);
            }
        }
        return result;
    }
}

你可能感兴趣的:(算法训练营,算法,数据结构,leetcode)