zoukankan      html  css  js  c++  java
  • LeetCode 42接雨水 按行求解(差分+排序)

    按行求解的思路比较清晰明了,但是这个方法的复杂度高达O(heightSize*sum(height[i])),几乎高达O(N^2)。
    但是也并不是不可以解决,经观察我们可以发现,这个算法的缺点在于要遍历每一个柱体的每一个高度,所以解决的时就要从这个点着手。
    设之前已经存在的柱体的最高高度为bp,当前柱体的高度为h,则如果h<=bp,说明该高度和它以下的高度已经出现过,我们更新该高度的end位置(end一直增加,所以不需要比较)。
    但是,如果bp<h,说明只有bp以下的高度之前出现过,我们只能更新bp高度以下柱体的end,对于高于bp的,我们记录它的第一次出现位置,就是当前位置i。
    对于更新end数组,我们定义一个结构体node,存放不同高度柱体对应的end和它本身的高度,因为我们之后要排序。
    更新完成node结构体数组,按照end降序排序,对于end是不会相同的,所以不用考虑end相同时的情况。
    此时node数组中的第一个end就是最右边的end,并且带有对应的高度h,此时小于等于高度h的柱体的右边界就确定下来,这时小于等于h的答案就可以求出来了,我们之后就不用求小于这个高度h的答案了。
    定义一个cur_height表示已经求过的高度,后面的node中存放的情况有两种,第一种是高度小于cur_height的,说明,之前也出现过这个高度,但是出现的位置比较靠前,不与考虑。
    第二种情况就是,高度大于cur_height的,说明,在此之前有高度更高的柱体出现过,求解cur_height+1~node[i].height即可。
    对于每一层的方块数,差分求就可以了啦。。。。
    献上代码,瞎搞写法,开心,,,,

    #include <algorithm>
    #include <string.h>
    using namespace std;
    const int maxn=1e5+10;
    
    int cnt[maxn],beg[maxn];
    
    struct Node {
        int end,h;
    }node[maxn];
    
    bool cmp(const Node &a,const Node &b)
    {
        return a.end>b.end;
    }
    
    class Solution {
    public:
        int trap(vector<int>& height) {
            
            memset(node,0,sizeof(node));
            memset(cnt,0,sizeof(cnt));
            
            int ans=0,size=height.size();
            int bp=0,p;
            for (int i=0;i<size;i++) {
                if (height[i]) {
                    cnt[1]++;
                    cnt[height[i]+1]--;
                }
                p=min(bp,height[i]);
                node[p].h=p;
                node[p].end=i;
                for (int j=bp+1;j<=height[i];j++) {
                    beg[j]=i;
                }
                if (bp<height[i]) {
                    bp=height[i];
                }
            }
    
            int add=0;
            for (int i=1;i<=bp;i++) {
                add+=cnt[i];
                cnt[i]=add;
            }
    
            sort(node,node+bp+1,cmp);
            int cur_height=0;
            for (int i=0;node[i].end;i++) {
                if (node[i].h>cur_height) {
                    for (int j=cur_height+1;j<=node[i].h;j++) {
                        ans+=node[i].end-beg[j]+1-cnt[j];
                    }
                    cur_height=node[i].h;
                }
            }
            return ans;
        }
    };
    
  • 相关阅读:
    【UVa#10325】The Lottery
    【洛谷P1868】饥饿的奶牛
    【NOI2005】维护数列
    【NOIP2018】保卫王国
    【洛谷P4719】动态dp
    【NOI2014】魔法森林
    【洛谷P4234】最小差值生成树
    【国家集训队】Tree II
    面试1
    struts2中的方法的调用
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/12328869.html
Copyright © 2011-2022 走看看