其他分享
首页 > 其他分享> > 力扣题-使用单调栈接雨水

力扣题-使用单调栈接雨水

作者:互联网

  1. 项目1
/**1.有雨水的地方一定是两端高,中间低
 * 2.方式1是通過查找當前節點的左右兩端(不一定是相鄰兩端)是否高於當前節點
 * 3.方式2是通過構建單調棧來計算雨水面積
*/
//方法1
class Solution {
    public int trap(int[] height) {
  		  /*這裡只是為了獲取左、右遍歷數組*/
       int[] left = this.leftMin(height);
       int[] right = this.rightMax(height);
       //返回值
       int ans = 0;
       
       for(int i = 0; i < height.length;i++){
       		//這裡可以使用Math.min()方法減少比較
           if(left[i] < right[i]){
          //面積計算是根據兩端最低減去當前節點值
               ans = ans + left[i] - height[i];
           }else if(left[i] > right[i]){
               ans = ans + right[i] - height[i];
           }
       }
       return ans;
    }
	//獲取任意節點的左遍歷獲得的最大值
    private int[] leftMin(int[] height){

        int length = height.length;
        int temp = height[0];
        int k = 0;
        int[] left = new int[length];

        for(int i = 0;i < length;i++){

            if(height[i] > temp){

                left[k++] = height[i];
                temp = height[i];
            }else{

                left[k++] = temp;
            }
            
        }
        return left;
    }
	//獲取任意節點的右遍歷獲得的最大值
    private int[] rightMax(int[] height){

         int length = height.length;
        int temp = height[length - 1];
        int k = length - 1;
        int[] right = new int[length];
        
        for(int i = length - 1;i >= 0;i--){

            if(height[i] > temp){

                right[k--] = height[i];
                temp = height[i];
            }else{

                 right[k--] = temp;
            }
        }
        return right;
    }
}

//方法2
/*單調棧保存的是數組索引,索引從小到大,對應數組值是從大到小,
當數據值大於棧頂值對應數組,彈棧,直至棧頂數組值小於等於數據值,然後將數據值壓入棧中*/
class Solution{
    //使用单调栈计算面积
     public int trap(int[] height) {
        //创建单调栈
        int ans = 0;

        Deque<Integer> stack = new LinkedList<>();
        int length = height.length;
            
        for(int i = 0;i < length;i++){
			//压栈条件是栈中无数据,或者小于等于栈顶对应数组值
            while(!stack.isEmpty() && height[stack.peek()] < height[i]){
            
				//执行弹栈操作说明数据大于栈顶值
                int currentIndex = stack.pop();
				//弹栈之后判断栈顶是否有数据,没有数据退出while循环,执行压栈操作
                if(stack.isEmpty()){
                    break;
                }
                int leftIndex = stack.peek();
                //一般来说宽度为1,但是存在数组索引对应值相等的情况
                int width = i - leftIndex -1;
                ans = (Math.min(height[leftIndex],height[i]) - height[currentIndex]) * width + ans;         
            }
            stack.push(i);
        }
    return ans;
    }
}


标签:right,temp,int,力扣题,height,length,ans,单调,栈接
来源: https://blog.csdn.net/weixin_45683782/article/details/115717618