代码随想录第29天:贪心

134. 加油站

复制代码
class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        for(int i=0;i<gas.size();i++)
        {
            int rest=gas[i]-cost[i];
            int index=(i+1)%gas.size();
            while(rest>0&&index!=i)//要剩余油量大于0才能到下一个节点,而且要判断是否回到原点
            {
                rest=rest+(gas[index]-cost[index]);
                index=(index+1)%gas.size();
            }
            if(rest>=0&&index==i)
            {
                return i;
            }

        }
        return -1;
    }
};

暴力解法,但判断那种环形循环是一般用while循环。

这道题目通过判断以每一个点为起始节点看是否能回到原点,这道题目的关键是while循环内的内容,要rest>0且index!=i,即要剩余油量大于0才能移动到下一个节点,且要判断是否回到原点,回到原点就中断循环。

复制代码
class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int totalsum=0;
        int cursum=0;
        int start=0;
        for(int i=0;i<gas.size();i++)
        {
            totalsum=totalsum+gas[i]-cost[i];
            cursum=cursum+gas[i]-cost[i];
            if(cursum<0)
            {
                cursum=0;
                start=i+1;
            }
        }
        if(totalsum<0)
        {
            return -1;
        }
        return start;
    }
};

从第一个位置开始计算,当出现油量为负数时,从开始到当前的位置结点所有都符合题意,只能从下一个节点为开始节点继续计算,因为题目中已经说了只有一个节点开始满足题意,所以肯定会出现,cursum>0的情况。

​​​​​​135. 分发糖果

复制代码
class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> res(ratings.size());
        res[0]=1;
        for(int i=1;i<ratings.size();i++)
        {
            if(ratings[i]>ratings[i-1])
            {
                res[i]=res[i-1]+1;
            }
            else
            {
                res[i]=1;
            }
        }
        res[ratings.size()-1]=max(res[ratings.size()-1],1);
        for(int i=ratings.size()-2;i>=0;i--)
        {
            if(ratings[i]>ratings[i+1])
            {
                res[i]=max(res[i+1]+1,res[i]);
            }
            else
            {
                res[i]=max(res[i],1);
            }
        }
        int sum=0;
        for(int i=0;i<res.size();i++)
        {
            sum=sum+res[i];
        }
        return sum;
    }
};

分发糖果要分开看,在哪从左向右看,再从右向左看,这两个取一个最大值

简化代码

复制代码
class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> res(ratings.size(),1);
        for(int i=1;i<ratings.size();i++)
        {
            if(ratings[i]>ratings[i-1])
            {
                res[i]=res[i-1]+1;
            }
        }
        for(int i=ratings.size()-2;i>=0;i--)
        {
            if(ratings[i]>ratings[i+1])
            {
                res[i]=max(res[i],res[i+1]+1);
            }
        }
        int sum=0;
        for(int i=0;i<res.size();i++)
        {
            sum+=res[i];
        }
        return sum;
    }
};

860. 柠檬水找零

复制代码
class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        if(bills[0]!=5)
        {
            return false;
        }
        int five=0;
        int ten=0;
        int twenty=0;
        for(int i=0;i<bills.size();i++)
        {
            if(bills[i]==5)
            {
                five++;
                continue;
            }
            else if(bills[i]==10)
            {
                if(five>=1)
                {
                    five--;
                    ten++;
                    continue;
                }
                else
                {
                    return false;
                }
            }
            else if(bills[i]==20)
            {
                if(ten>=1&&five>=1)
                {
                    five=five-1;
                    ten--;
                    twenty++;
                    continue;
                }
                else if(five>=3)
                {
                    five=five-3;
                    twenty++;
                    continue;
                }
                else
                {
                    return false;
                }

            }
        }
        return true;
    }
};

把各种情况写下来,进行判断就可以了,但是要注意,先花10元的再花5元的

406. 根据身高重建队列

复制代码
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) {
        sort(people.begin(),people.end(),cmp);
        vector<vector<int>> res;
        for(int i=0;i<people.size();i++)
        {
            int p=people[i][1];
            res.insert(res.begin()+p,people[i]);
        }
        return res;
    }
};

对于多种维度的问题,要先确定一个维度,再思考另一个维度

相关推荐
先吃饱再说10 小时前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰13 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术14 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六17 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术18 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize19 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考1 天前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
CSharp精选营1 天前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
美团技术团队1 天前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法