leetcode 42接雨水

接雨水

  • 暴力法
    直接记录左右最大,最后加上当前节点左右较小的与当前的差
func trap(height []int) int {
	res:=0
	if len(height)==0{
		return 0
	}
	lmax:=make([]int,len(height))
	rmax:=make([]int,len(height))
	lmax[0]=height[0]
	//保留左右每个节点对应方向的最大值
	rmax[len(height)-1] = height[len(height)-1]
	for i:=1;i<len(height);i++{
		lmax[i] = max(lmax[i-1],height[i])
	}
	
	for i:=len(height)-2;i>=0;i--{
		rmax[i] = max(rmax[i+1],height[i])
	}
	//节点i左右相对小的决定能盛多少水
	for i:=0;i<len(height);i++{
		res+=min(lmax[i],rmax[i])-height[i]
	}
	return res
}

func max(x,y int)int {
	if x>y{
		return x
	}else{
		return y
	}
}

func min(x,y int)int  {
	if x>y{
		return y
	}else{
		return x
	}
}

  • 左右指针
    左右保留最大,left和right和相应方向的最大值比较
    记录值
func trap(height []int) int {
	res:=0
	if len(height)==0{
		return 0
	}
	//保留左右最大
	lmax,rmax:=height[0],height[len(height)-1]
	l,r:=0,len(height)-1
	for l<=r{
		lmax  = max(lmax,height[l])
		rmax  = max(rmax,height[r])
		if lmax>rmax{
			res+= rmax-height[r] //不会为负数,因为是最大值
			r--
		}else{
			res += lmax-height[l]
			l++
		}
	}
	return res
}

func max(x,y int)int {
	if x>y{
		return x
	}else{
		return y
	}
}
  • 单调栈

func trap(height []int) int {
    //和84柱状图最大面积类似,但是是单调递减的栈
    //不需要增加辅助接节点,因为只有一个元素无法接到雨水,右边末端为最小也无发构造凹槽
    // 计算方式为凹槽和两边高度较小的差值为h,两边之间的距离为宽度w,乘积为面积
    stack:=[]int{}
    res:=0
    for i:=0;i<len(height);i++{
        for len(stack)!=0&&height[i]>height[stack[len(stack)-1]]{
            h:=height[stack[len(stack)-1]]
            stack = stack[:len(stack)-1]
            if len(stack)==0{
                break
            }
            l:=stack[len(stack)-1]
            minH:=min(height[i],height[l])-h //高度为两边较小-h
            w:=i-l-1
            res += w*minH
        }
        stack =append(stack,i)
    }
    return res
}


func min(x,y int)int{
    if x>y{
        return y
    }else{
        return x
    }
}

84 柱状图中最大的矩形

方法一

方法二

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        if(heights.empty())
            return 0;
        //左右单调栈
        vector<int>left(heights.size()),right(heights.size(),heights.size());
        int sum = 0;
        stack<int>sta;
        for(int i=0;i<heights.size();i++)
        {
            while(!sta.empty()&&heights[sta.top()]>=heights[i])
            {
                 right[sta.top()]=i;
                sta.pop();
            }
            left[i] = sta.empty()?-1:sta.top();
            sta.push(i);
        }
        
        for(int i=0;i<heights.size();i++)
        {
            sum = max(sum,heights[i]*(right[i]-left[i]-1));
        }

        return sum;
        
    }
};
posted @ 2021-02-04 15:38  海拉尔  阅读(42)  评论(0编辑  收藏  举报