Leetcode刷题_贪心相关_c++版

(1)455分发饼干–简单

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
在这里插入图片描述

class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {//升序排序sort(g.begin(), g.end());sort(s.begin(), s.end());int cookie = 0;int child = 0;//贪心算法,尽可能用小饼干满足更多孩子while(cookie < s.size() && child < g.size()){if(g[child] <= s[cookie]){//该孩子满足了,满足下一个孩子child++;}//如果未满足,则当前饼干一定不能满足剩下的孩子,移动到下一块//如果满足,则当前饼干被消耗,移动到下一块cookie++;}return child;}
};

在这里插入图片描述

(2)376摆动序列–中等

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。

例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。

相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。

给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。
在这里插入图片描述
在这里插入图片描述
连续递增或递减时,选择红色点

class Solution {
public:int wiggleMaxLength(vector<int>& nums) {if(nums.size()==0) return 0;if(nums.size()==1) return 1;//利用状态机转换//三个状态static const int begin = 0;static const int up = 1;static const int down = 2;int STATE = begin;int maxLength = 1;//初始长度为1for(int i = 1; i< nums.size(); i++){switch(STATE){//当状态为begin时case begin:if(nums[i]>nums[i-1]){STATE = up;maxLength++;}else if(nums[i] < nums[i-1]){STATE = down;maxLength++;}//如果两数相等,不发生状态转换break;case up:if(nums[i] < nums[i-1]){STATE = down;maxLength ++;}//如果两数相等或后一个大于前一个,不发生状态转换break;case down:if(nums[i] > nums[i-1]){STATE = up;maxLength ++;}//如果两数相等或后一个小于前一个,不发生状态转换break;}}return maxLength;}
};

在这里插入图片描述

(3)402移调k位数–中等

给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
在这里插入图片描述

#include<string>
using namespace std;
class Solution {
public:string removeKdigits(string num, int k) {if(k >= num.size()) return "0";vector<int> S;string result = "";int number;for(int i = 0; i< num.length(); i++){//从高位开始,保留尽可能小的数number = num[i] - '0';//字符串转换为数字,0要用单引号,表示一个字符,双引号表示一个字符串while(S.size()> 0 && number < S[S.size() - 1] && k>0){//if(S.size() == 1 && number == 0) break;//如果栈中只有一个元素,且新来的元素是0,不能用0替换栈顶S.pop_back();//如果新元素比栈顶小,就保留新元素k--;}//0不能作为开头元素if(number != 0 || S.size() != 0 ){S.push_back(number);}}if(S.size() == 0 || k >= S.size()) return "0";//如果序列都遍历完而k还未用完时,得到的栈中元素一定是单调递增的。while(k > 0) {S.pop_back();k--;}if(S.size() == 0) return "0";for(int i = 0; i< S.size(); i++){//char tmp = S[i]+'0';//result = result+ tmp;//这样转字符,超长用例会报超时,不知道为啥result.append(1,S[i]+'0');//在当前字符串结尾添加1个字符}return result;}
};

在这里插入图片描述
append函数的用法参考:https://blog.csdn.net/weixin_42258743/article/details/107964192

(4)55跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。
在这里插入图片描述

法一:

class Solution {
public:bool canJump(vector<int>& nums) {//关键在于如何选择下一条的节点//下一跳能跳的越远越有利,因此选择能达到最远的节点if(nums.size()== 1) return true;int next_index = -1;int index = 0;int max_distance = 0;//此处赋值为负数的话会导致与size函数返回值(无符号数)比较出错while((index+max_distance <= (nums.size()-1)) && (next_index != index)){//下一跳等于当前下标,则证明不能到达//下一条等于大于总长度,则证明可到达max_distance = 0;//index更新至下一跳处if (next_index != -1) index = next_index;//cout<<"index = "<< index << " next_index = "<<next_index<<endl;if(nums[index] == 0) break;else{for(int i = 1; i<= nums[index] && (i+index<nums.size()); i++){//遍历从index到index+nums[i]能到达的所有元素,找出最远距离if((i+nums[i+index]) > max_distance){max_distance = (i+nums[i+index]);next_index = index+i;//cout<< " i="<<i<<" max_distance=" << max_distance<<endl;}}}//cout<<"index = "<< index << " next_index = "<<next_index<<endl;}if((index+max_distance >= (nums.size()-1)) ) return true;return false;}
};

在这里插入图片描述

法二:

class Solution {
public:bool canJump(vector<int>& nums) {if(nums.size() == 1) return true;int length = nums.size();//总长度int tmp = nums[0];//tmp记录当前能到达的最远距离int i = 1;for(i; (i< length && tmp > 0); i++){tmp--;cout<< "tmp="<<tmp<<" nums[" << i<<"]=" << nums[i]<< " ";//如果当前节点能到达的距离比之前的远,tmp更新为当前节点的值if(nums[i] > tmp){ tmp = nums[i];}//cout<< tmp << "picked"<<endl;}//cout<< "tmp="<<tmp<<endl;if(i >= length && tmp >= 0) return true;return false;}
};

在这里插入图片描述

(5)45跳跃游戏二–中等

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

0 <= j <= nums[i]
i + j < n
返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。

在这里插入图片描述
此题根据跳跃游戏的 法一 改编得到
https://blog.csdn.net/weixin_44343355/article/details/128772719

class Solution {
public:int jump(vector<int>& nums) {//关键在于如何选择下一条的节点//下一跳能跳的越远越有利,因此选择能达到最远的节点if(nums.size() < 2) return 0;int next_index = 0;int index = 0;int max_distance = nums[0];//此处赋值为负数的话会导致与size函数返回值(无符号数)比较出错int jump_times = 0;int length = nums.size();while(((max_distance) < length -1)){//最远能到的距离等于大于总长度,则证明可到达for(int i = 1; i<= nums[index] && (i+index<nums.size()); i++){//遍历从index到index+nums[i]能到达的所有元素,找出最远距离if((i+nums[i+index]+index) > max_distance){max_distance = (i+nums[i+index]+index);next_index = index+i;//cout<< " i="<<i<<" max_distance=" << max_distance<<endl;}}index = next_index;jump_times++;}return jump_times+1;}
};

在这里插入图片描述

(6)452用最少数量的箭引爆气球–中等

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。

给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。

在这里插入图片描述

//注意,此处需要加引用
bool cmp(const vector<int> &a, const vector<int> &b){return a[0] < b[0];
}class Solution {
public:int findMinArrowShots(vector<vector<int>>& points) {if(points.size() == 1) return 1;sort(points.begin(), points.end(), cmp);//按左端点从小到大升序排序int length = points.size();int shootNum = 1;int shooter_begin = points[0][0];int shooter_end = points[0][1];for(int i = 1;i<length;i++){//如果新节点的左端点在shooter的范围内,则说明两区间有重合部分,需要一箭即可射穿if(points[i][0] >= shooter_begin && points[i][0] <= shooter_end){//更新shooter的左端点shooter_begin = points[i][0];//如果shooter的右端点大于新节点的右端点,则更新右端点if(points[i][1] <= shooter_end){shooter_end = points[i][1];}}//如果无交集,则新选择一个射手else{shootNum++;shooter_begin = points[i][0];shooter_end = points[i][1];}}return shootNum;}
};

在这里插入图片描述

(7)871最低加油次数–困难

汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处。

沿途有加油站,用数组 stations 表示。其中 stations[i] = [positioni, fueli] 表示第 i 个加油站位于出发位置东面 positioni 英里处,并且有 fueli 升汽油。

假设汽车油箱的容量是无限的,其中最初有 startFuel 升燃料。它每行驶 1 英里就会用掉 1 升汽油。当汽车到达加油站时,它可能停下来加油,将所有汽油从加油站转移到汽车中。

为了到达目的地,汽车所必要的最低加油次数是多少?如果无法到达目的地,则返回 -1 。

注意:如果汽车到达加油站时剩余燃料为 0,它仍然可以在那里加油。如果汽车到达目的地时剩余燃料为 0,仍然认为它已经到达目的地。

在这里插入图片描述
此题的思路与跳跃游戏二中的思路类似,都是求最小跳跃次数,用贪心的思想

class Solution {
public:int minRefuelStops(int target, int startFuel, vector<vector<int>>& stations) {if(stations.size() == 0){if(target > startFuel) return -1;else return 0;}// if(stations.size() == 1){//     if(target < startFuel) return 0;//     else if(stations[0][0] > startFuel || (stations[0][1]+startFuel) < target) return -1;//     else return 1;// }int leftFuel = startFuel;//剩余油量priority_queue<int, vector<int>, less<int>> maxFuel;//途中站点的最大油量,加过油的站点就不能再加油了,所以用 堆来存储,依次输出最大站点int addFuelTimes = 0;//加油次数int i = 0;int maxfuel = 0;vector<int> target_vector;target_vector.push_back(target);target_vector.push_back(0);stations.push_back(target_vector);for(i = 0; i< stations.size(); i++){//cout<< "i="<<i<<" ";leftFuel = startFuel - stations[i][0];//剩余油量//剩余油量小于等于0,则表明过程中需要加一次油//无法到达该点,先加油while(leftFuel < 0 && maxFuel.size()>0){maxfuel = maxFuel.top();maxFuel.pop();leftFuel = leftFuel + maxfuel;startFuel = startFuel +maxfuel;addFuelTimes ++;}if(leftFuel<0) return -1;maxFuel.push(stations[i][1]);//前面所有站点的油都加完了,如果还到不了该点,返回无法到达//cout<<endl;}return addFuelTimes;}};  

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/108125.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux设备树节点添加新的复位属性之后设备驱动加载异常问题分析

linux设备树节点添加新的复位属性之后设备驱动加载异常问题分析 1 linux原始设备驱动信息1.1 设备树节点信息1.2 linux设备驱动1.3 makefile1.4 Kconfig1.5 对应的defconfig文件 2 修改之后的linux设备驱动2.1 修改之后的设备树节点信息2.2 原始test_fw.c出现的问题以及原因分析…

(CVPR-2023)InternImage:利用可变形卷积探索大规模视觉基础模型

InternImage&#xff1a;利用可变形卷积探索大规模视觉基础模型 Title&#xff1a;InternImage: Exploring Large-Scale Vision Foundation Models with Deformable Convolutions paper是上海AI Lab发表在CVPR 2023的工作 paper链接 Abstract 与近年来大规模视觉变换器&#x…

3ds max文件打包?max插件CG Magic一键打包整起!

3ds max文件如何打包&#xff1f;这个问题&#xff0c;小编听到不少网友的提问&#xff01; 今天CG Magic小编来和大家聊聊&#xff0c;文件更高效的操作&#xff0c;如何打包处理呢&#xff1f; 3DMAX这款软件的受众群体是比较高的&#xff0c;在工作方便的同时&#xff0c;…

buuctf crypto 【robomunication】解题记录

1.文件是MP3文件&#xff0c;打开听&#xff0c;很明显的摩斯电码&#xff0c;写下摩斯密码 ...././.-../.-../---/.--/..../.-/-/../.../-/...././-.-/./-.--/..-/../.../-.../---/---/.--./-.../././.--. 2.解密一下 3.flag即为BOOPBEEP

C语言之指针进阶篇(3)

目录 思维导图 回调函数 案例1—计算器 案例2—qsort函数 关于qsort函数 演示qsort函数的使用 案例3—冒泡排序 整型数据冒泡排序 回调函数搞定各类型冒泡排序 cmp_int比较大小 cmp传参数 NO1. NO2. 解决方案 交换swap 总代码 今天我们学习指针难点之回调函数…

虹科方案 | HK-NEOs系列带来先进的磁带自动化解决方案

一、HK-NEOs 系列自动磁带库 通常只有在昂贵的企业解决方案中才能找到的高级功能&#xff0c;我们的入门级磁带自动化产品就能够具备。使用 HK-NEOs 系列自动化磁带库&#xff0c;可以获得远程管理、可拆卸盒式磁带卷、可升级磁带驱动器、条形码阅读器等更多功能。 但这还不是…

5.10.WebRTC接口宏

那今天呢&#xff1f;我给大家介绍一下web rtc的接口宏&#xff0c;那之所以在现成的章节中要介绍接口宏。是由于接口在调用的过程中啊&#xff0c;会发生线程的切换&#xff0c;所以把接口宏这部分知识我们放在线程这一章还算比较合适的。 那另外呢&#xff0c;我们对于接口…

Django05_反向解析

Django05_反向解析 5.1 反向解析概述 随着功能的不断扩展&#xff0c;路由层的 url 发生变化&#xff0c;就需要去更改对应的视图层和模板层的 url&#xff0c;非常麻烦&#xff0c;不便维护。这个时候我们可以通过反向解析&#xff0c;将 url解析成对应的 试图函数 通过 path…

Botowski:SEO友好的AI内容生成器

【产品介绍】 名称 Botowski 具体描述 Botowski是一个人工智能内容生成器&#xff0c;可以被撰稿人、企业主和其他人用来创建高质量的内容。 它可以创建各种主题的文章、博客文章&#xff0c;甚至散文。Botowski的设计是用户友好的;你所需要做…

CSS3技巧36:backdrop-filter 背景滤镜

CSS3 有 filter 滤镜属性&#xff0c;能给内容&#xff0c;尤其是图片&#xff0c;添加各种滤镜效果。 filter 滤镜详见博文&#xff1a;CSS3中强大的filter(滤镜)属性_css3滤镜_stones4zd的博客-CSDN博客 后续&#xff0c;CSS3 又新增了 backdrop-filter 背景滤镜。 backdr…

长亭雷池社区版本安装与使用

0x01 雷池介绍 一款足够简单、足够好用、足够强的免费 WAF。基于业界领先的语义引擎检测技术&#xff0c;作为反向代理接入&#xff0c;保护你的网站不受黑客攻击。核心检测能力由智能语义分析算法驱动&#xff0c;专为社区而生&#xff0c;不让黑客越雷池半步。 官方网址&…

利用Semaphore实现多线程调用接口A且限制接口A的每秒QPS为10

前段时间在群里面发现有个群友抛出一个实际需求&#xff1a;需要通过一个接口拉取数据&#xff0c;这个接口有每秒10QPS限制&#xff0c;请问如何实现数据拉去效率最大化且限制调用拉取接口每秒10PQPS&#xff1f;我觉得这个需求挺有意思的&#xff0c;跟某群友讨论&#xff0c…