当前位置: 首页 > news >正文

day29-贪心__134. 加油站__135. 分发糖果__860.柠檬水找零__406.根据身高重建队列

134. 加油站

这道题的贪心方法相当的巧妙。

首先,我们可以通过gas[i] - cost[i]得到第i个站点的净加油量(耗油量),那么如果我们现在考虑一个从某点a到某点b,那么如果a-》b范围之间的gas[i] - cost[i]存在负数,那么说明无法从a作为起点到达b,那么我们就必须考虑从b+1,开始作为起点。那为什么不从a+1或者a->b中的某一点到达呢,这里可以使用反证法证明出来,详情见:链接。

此外我们可以同时维护一个totalSum,如果totalSum<0,说明无论从那个点出发,都无法绕行一周。

代码如下:

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        for (int i = 0; i < cost.size(); i++) {
            int rest = gas[i] - cost[i]; // 记录剩余油量
            int index = (i + 1) % cost.size();
            while (rest > 0 && index != i) { // 模拟以i为起点行驶一圈(如果有rest==0,那么答案就不唯一了)
                rest += gas[index] - cost[index];
                index = (index + 1) % cost.size();
            }
            // 如果以i为起点跑一圈,剩余油量>=0,返回该起始位置
            if (rest >= 0 && index == i) return i;
        }
        return -1;
    }
};

135. 分发糖果

这道题的话,我们主要要同时考虑一个元素的左右两个位置,如果我们在一次循环中同时处理左右位置的话,这显然会很复杂。但是现在,我们可以考虑将同时考虑左右两个位置,转换为单独考虑左侧之后,再单独考虑右侧。

单独考虑左侧时,如果当前元素大于前一个元素,那么所给的糖果数量就是前一个位置的糖果数量加1。

考虑完左侧之后,考虑右侧。但是这里就有问题了,这一次我们还是从左往右遍历嘛。显然不对,因为我们考虑右侧时,每一个位置的结果,都要依赖于其左侧的元素得出。所以我们的遍历顺序也必须是从右到左。

当后一个元素大于当前元素时,该位置的糖果数量就是单独考虑左侧时的糖果数量和后一个元素的糖果数量+1取最小值,这样能保证我们最终得到的糖果是最少的。

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        for (int i = 0; i < cost.size(); i++) {
            int rest = gas[i] - cost[i]; // 记录剩余油量
            int index = (i + 1) % cost.size();
            while (rest > 0 && index != i) { // 模拟以i为起点行驶一圈(如果有rest==0,那么答案就不唯一了)
                rest += gas[index] - cost[index];
                index = (index + 1) % cost.size();
            }
            // 如果以i为起点跑一圈,剩余油量>=0,返回该起始位置
            if (rest >= 0 && index == i) return i;
        }
        return -1;
    }
};

860.柠檬水找零

这道题其实相当简单,因为给的场景很固定,我们只需要维护三个变量five ten 和 twenty的值。

当顾客给五元时,five++即可;

当顾客给十元时,查看five是否>=1,如果不满足就返回false。满足就ten++,five++;

当顾客给二十元时,这个时候就有了两种处理方案,一种是找三张5元,另一种是一张10元,一张5元。那么我们应该优先选择哪一种呢。当然是10+5啦!因为5元再找零时作用更大,所以先选择10+5的方式进行找零。

所以这样代码就很容易了

代码如下:

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

406. 根据身高重建队列

这道题,每个vector都有两个维度,一个是身高h,另外一个是前面有多少个人比起更高k。这里如果我们选择按照身高h对这些vector进行一次递减排序,那么我们第二次处理k的话会相当的方便。

代码如下:

class Solution {
public:
    // 身高从大到小排(身高相同k小的站前面)
    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);
        list<vector<int>> que; // list底层是链表实现,插入效率比vector高的多
        for (int i = 0; i < people.size(); i++) {
            int position = people[i][1]; // 插入到下标为position的位置
            std::list<vector<int>>::iterator it = que.begin();
            while (position--) { // 寻找在插入位置
                it++;
            }
            que.insert(it, people[i]);
        }
        return vector<vector<int>>(que.begin(), que.end());
    }
};
http://www.dtcms.com/a/123377.html

相关文章:

  • 三分钟学会使用java RandomAccessFile随机读写IO
  • 数字内容体验的技术支持包含什么?
  • 公司内部建立apt源
  • Animated Movement Color
  • 【书籍】DeepSeek谈《持续交付2.0》
  • 第5篇:Linux程序访问控制FPGA端LEDR<三>
  • 如何用 nvm alias default 18.20.8 实现全局 Node.js 版本管理?一篇保姆级指南!!!
  • 深入解析回环检测:从原理到C++实战
  • 批量清空图片的相机参数、地理位置等敏感元数据
  • 电商素材革命:影刀RPA魔法指令3.0驱动批量去水印,实现秒级素材净化
  • 【C++】右值引用、移动语义与完美转发
  • 【倍增】P10264 [GESP202403 八级] 接竹竿|普及+
  • java继承练习
  • 走多远(拓扑排序,dp)
  • ChatRoom测试报告
  • 手眼标定-眼在手上
  • 安卓设备配置PAC代理服务器的完整指南:实现智能分流与开发加速
  • OfficePlus去掉PDF文件右键菜单里的PDF转换
  • Java Map和Set集合应用
  • docker安装nginx,基础命令,目录结构,配置文件结构
  • 0410 | 软考高项笔记:项目管理概述
  • jQuery多库共存
  • 甘特图和里程碑趋势图在项目监控中有哪些实际应用?
  • 本地laravel项目【dcat-admin】部署到liunx服务器
  • 论文笔记:Dynamic Spectral Graph Anomaly Detection
  • 先占个日常,等会写。
  • 如何白嫖Grok3 API? 如何使用Grok3 API调用实例?怎么使用Grok3模型?
  • 从零实现Agent智能体配置使用(Ragflow)
  • 多模态大模型在目标检测领域的最新进展
  • JS包装类型Object