代码随想录算法训练营Day29||Leetcode 134. 加油站 、 135. 分发糖果 、860.柠檬水找零 、 406.根据身高重建队列

一、加油站

        先剪枝,如果燃烧汽油数组中的总和大于补充的话,直接返回-1,即不成立的情况。然后讨论成立能跑完的情况,作差值,对差值进行叠加遍历(rest的+=操作)如果从前面开始,已经出现了rest<0的情况,那么起始点一定不能选在前面,一定是从当前遍历到结果<0的点之后才能开始跑完,并且这种算法忽略了对环的考虑。

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int sum1=0,sum2=0;
        for(int i=0;i<gas.size();i++){
            sum1+=gas[i];
            sum2+=cost[i];
        }
        if(sum1<sum2)return -1;
        
        else {
            int start=0;
            int rest=0;
            for(int i=0;i<gas.size();i++){
                rest+=gas[i]-cost[i];
                if(rest<0){
                    start=i+1;
                    rest=0;
                }

            }
            return start;
        }
    }
};

二、分发糖果

        本题先从左遍历,保证从左到右是满足题意的,再从右向左遍历,使其满足题意。要注意,从右向左遍历到时候,如果按照规则来是让左侧分得的糖果比右边分得的数量多一,但是如果原来从左向右分得的更多,那就要保留原来分得的数量,因此要取一个最大值

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int>candys(ratings.size(),1);
        int sum=0;
        for(int i=1;i<ratings.size();i++){
            
            if(ratings[i]>ratings[i-1])candys[i]=candys[i-1]+1;
        }
        for(int i=ratings.size()-1;i>=1;i--){
            if(ratings[i-1]>ratings[i])candys[i-1]=max(candys[i-1],candys[i]+1);
        }
        for(int i=0;i<candys.size();i++){
            sum+=candys[i];
        }

        return sum;
    }
};

三、 柠檬水找零

        一遍过,简单

class Solution {
public:
    bool lemonadeChange(vector<int>& nums) {
        int sum5=0;
        int sum10=0;
        for(int i=0;i<nums.size();i++){
            if(nums[i]==5)sum5++;
            else if(nums[i]==10){
                sum5--;
                sum10++;
            }
            else if(nums[i==20]){
                if(sum10!=0){
                    sum10--;
                    sum5--;
                }
                else if(sum10==0){
                    sum5=sum5-3;
                }
                
            }
            

            if(sum5<0||sum10<0)return false;
        }
        return true;
    }
};

 四、根据身高重建队列

        这题见识到了sort函数的强大,我一直在想这个二维数组怎么排列。

        然后排列好之后,把前面有几个比自己大对应的数量k作为新数组的下标插入操作也很让我佩服,直接插入既利用了数组的下标特性,又能保证后面的元素不断更新(如果插在同一个位置就是后来者占据这个位置,而后来者恰恰是我们排序后较小的元素,即使原来这个位置元素被顶替,也不会影响结果)

class Solution {
public:
    static bool cmp(const vector<int>&a,const vector<int>&b){
        if(a[0]==b[0])return a[1]<b[1];
        return a[0]>b[0];
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        vector<vector<int>>result;
        sort(people.begin(),people.end(),cmp);
        for(int i=0;i<people.size();i++){
            int position=people[i][1];
            result.insert(result.begin()+position,people[i]);
        }
        return result;
    }
};

然后补充一下回调函数

如果想让原数组按降序排列:

 static bool cmp(const vector<int>&a,const vector<int>&b){
        if(a[0]==b[0])return a[1]<b[1];
        return a[0]>b[0];
    }

升序排列:

 static bool cmp(const vector<int>&a,const vector<int>&b){
        if(a[0]==b[0])return a[1]<b[1];
        return a[0]<b[0];
    }

 只有返回值符号的不同。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值