【线性扫描ijk_贪心】candy 最少蛋糕分配、Trapping Rain water

这篇博客探讨了两个编程问题:Candy问题,要求在满足一定条件的情况下分配最少的糖果,确保每个孩子至少有一块;以及Trapping Rain Water问题,计算在给定的海拔地图中可以捕获多少雨水。对于Candy问题,解决方案需保证评级高的孩子获得更多的糖果;对于Trapping Rain Water,通过遍历数组找到水洼的最大容量。
摘要由CSDN通过智能技术生成

Candy

  Total Accepted: 14466  Total Submissions: 78095 My Submissions

There are N children standing in a line. Each child is assigned a rating value.

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

What is the minimum candies you must give?

class Solution {
public:
    int candy(vector<int> &ratings) {
        int n=ratings.size();
        vector<int> &t=ratings;
        vector<int> r(n,0);

        int i=0;
        while(true){
            int j=i;
            //down 
            while(j<n-1&&t[j+1]<t[j])  j++;
            int k=i;
            while(true) {
                if(k==i) r[k]=max(j-k+1,r[k]); //@warning the handle of the leftest element
                else r[k]=j-k+1;
                if(k==j) break;///end while
                k++;
            }
            
            //equal
            i=j;
            while(j<n-1&&t[j+1]==t[j]) j++,r[j]=1;
            
            //up
            i=j;
            while(j<n-1&&t[j+1]>t[j]) j++;
            k=i;
            while(true){
                r[k]=k-i+1;
                if(k==j) break;
                k++;
            }
            
            i=j;//@loop i
            if(i>=n-1) break;//end loop when i has reach the right endian of array t
        }
        int res=0;
        for(i=0;i<n;i++) res+=r[i];///@@error: here array r[i] fault as t[i]
        return res;
    }
};

Trapping Rain Water

  Total Accepted: 12662  Total Submissions: 44258 My Submissions

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example, 
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

此题关键是i,j,k的 线性扫描

j绑定到水洼的左边界

k绑定到j右边的第一个不小于A[j]的右边界;如果k溢出(找不到),则k改绑定到右边最大的值

然后计算(j,k)水洼的值。

再然后令i=k,开始新循环。

起名字(左边界,右边界)最好对应变量名字对仗,方便理解。

class Solution {
public:
    int trap(int A[], int n) {
        
        int area=0;
        int i=0;
        while(i<n){
            int j=i;
            int mL=A[i];//水洼左边界
            
            while(j<n-1&&A[j]<=A[j+1]) j++,mL=A[j];//A[j] is the extremal value after i ///@@@error:j++,mL=A[j],fault as lst=A[j],j++, then lst logically get a left smaller value
            
            int k=j+1; if(k>=n) break;
            int mR=0;//临时右边界
            while(k<n&&A[k]<mL) {//find a extremal 
                if(A[k]>mR) mR=A[k];
                k++;
            }
            
            int m=(k<n?mL:mR);///@error: m=(k<n?A[k]:mR); should be  m=(k<n?mL:mR);
            if(m==0) break; //没有水洼了
            for(k=j+1;A[k]<m;k++) area+=m-A[k];
            i=k;
        }
        return area;
    }
};

程序2:

class Solution {
public:
    int trap(int A[], int n) {
        if(n==0) return 0;
        int lH=A[0];//水洼左边界
        int area=0;
        int i=0;while(i<n-1){
            int rH=0,rX=i;  //i~rX 为水洼。rH为水洼临时右边界,初始为0
            int j;for(j=i+1;j<n;j++) {
                if(A[j]>=lH) {rX=j,rH=A[j];break;}//>=左边界的水洼右边界j
                if(A[j]>rH) rX=j,rH=A[j];//临时右边界
            }
            if(rX==i) break;//该水洼没有右边界。则后面也不存在水洼。
            //计算水洼面积
            int H=min(lH,rH);
            for(int k=i+1;k<rX;k++){ area+=H-A[k]; }
            //进入下一个水洼
            i=rX;lH=rH;
        }
        return area;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值