刷题之贪心3

前言

大家好,我是jiantaoyab,这篇文章将给大家介绍贪心算法和贪心算法题目的练习和解析,贪心算法的本质就是每一个阶段都是局部最优,从而实现全局最优。加上这篇文章一共有30道贪心题目了,加油!

坏了的计算器

image-20240323084010973

题目分析

image-20240323090707048

所以,只要tar<= sV,无论是奇数还是偶数都加1,当tar>sV时,奇数+1,偶数/2。

代码

class Solution {
public:int brokenCalc(int startValue, int target) {int count = 0;while(target > startValue){if(target % 2 == 0) target /= 2;else target += 1;count++;}//剩下target <= startValue 都是+1的//所以startValue - target 统计出有多少个1return count + startValue - target;}
};

合并区间

image-20240323091948868

题目分析

这种问题叫区间问题,一般先排序。这里用左端点排序。

image-20240323095428846

证明:能够合并的区间都是连续的

image-20240323100506949

代码

class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {vector<vector<int>> ret;//排序sort(intervals.begin(), intervals.end());int left = intervals[0][0], right = intervals[0][1];for(int i = 0; i < intervals.size(); i++){int l = intervals[i][0], r = intervals[i][1];if(l <= right){//有重叠部分right = max(right, r);}else{//没有重叠部分ret.push_back({left, right});left = l;right = r;}}ret.push_back({left, right});return ret;}
};

无重叠区间

image-20240323100619988

贪心的策略如果有重叠区间就移除右断点大的区间,如果没重叠区间的话说明这个区间不会和后面的区间重叠就保留下来,接着用下一个区间去和后面的区间判断。

代码

class Solution {
public:int eraseOverlapIntervals(vector<vector<int>>& intervals) {int count = 0;sort(intervals.begin(), intervals.end());int left = intervals[0][0], right = intervals[0][1];for(int i = 1; i < intervals.size(); i++){int l = intervals[i][0], r = intervals[i][1];if(l < right) {//有重叠部分count++;right = min(right, r);}else  {//没有重叠部分right = r;}}return count;}
};

用最少数量的箭引爆气球

image-20240325084609342

题目分析

这道题目和合并区间求的不一样,我们这里求的是交集。

image-20240325091858577

代码

class Solution {
public:int findMinArrowShots(vector<vector<int>>& points) {sort(points.begin(), points.end());int n = points.size();int ret = 1; //默认是有一个区间去和下一个区间进行比较int right = points[0][1];for(int i = 0; i < n; i++){int l = points[i][0], r = points[i][1];if(l <= right){//有交集right = min(r, right);}else{//没有交集ret++;right = r;}}return ret;}
};

整数替换

image-20240325092631599

题目分析

image-20240325102306024

代码

贪心思想来做

class Solution {
public:int integerReplacement(int n) {int count = 0;while(n != 1){if(n % 2 == 0) {n /= 2;count++;}else{if(n == 3){n = 1;count += 2;}         else if(n % 4 == 3) //说明是...11{n = n / 2 + 1;count += 2;}else //....01{count += 2;n /= 2;}}}return count;}
};

用记忆化搜索做

class Solution {unordered_map<int, int> hash;
public:int dfs(long long n){if(hash[n]) return hash[n];if(n == 1){hash[1] = 0;return 0;} if(n % 2 == 0){hash[n] = 1 + dfs(n / 2);return hash[n];}else{hash[n] = 1 + min(dfs(n + 1), dfs(n - 1));return hash[n];}}int integerReplacement(int n) {return dfs(n);}
};

俄罗斯套娃信封问题

image-20240325103044807

题目分析

image-20240325110947735

代码

不是很理解的可以看看第一篇贪心算法

class Solution {
public:int maxEnvelopes(vector<vector<int>>& envelopes) {sort(envelopes.begin(), envelopes.end(), [&](const vector<int>&v1, const vector<int>&v2){return v1[0] != v2[0] ? v1[0] < v2[0] : v1[1] >  v2[1];});vector<int> ret;ret.push_back(envelopes[0][1]);for(int i = 1; i < envelopes.size(); i++){int r = envelopes[i][1];if(r > ret.back()){ret.push_back(r);}else{int left = 0, right = ret.size() - 1;while(left < right){int mid = (left + right) / 2;if(ret[mid] >= r) right = mid;else left = mid + 1;}ret[left] = r;}}return ret.size();}
};

可被三整除的最大和

image-20240326191035787

题目分析

image-20240326193532737

引入一个新问题,如何求出最小值和次小值

image-20240326193915292

代码

class Solution {
public:int maxSumDivThree(vector<int>& nums) {const int INF = 0x3f3f3f3f;int x1 = INF, x2 = INF, y1 = INF, y2 = INF;int sum = 0;for(auto x : nums){sum += x;if(x % 3 == 1){if(x < x1) {x2 = x1;x1 = x;}else if(x < x2) x2 = x;}else if(x % 3 == 2){if(x < y1){y2 = y1;y1 = x;}else if(x < y2) y2 = x; }}if(sum % 3 == 0) return sum;else if(sum % 3 == 1) return max(sum - x1, sum - y1 - y2);else return max(sum - y1, sum - x1 - x2);}
};

距离相等的条形码

image-20240326195602785

题目分析

把数字间隔1个数字放,先放次数最多的,放下的数字的顺序怎么放都可以。

证明

题目一定是有解的,那么出现最多的那个数字不能超过 n + 1 / 2次,因为如果有n个抽屉,放n + 1 个东西,必然有一个抽屉放2个,分情况讨论。

如果最多出现的数字次数刚好是 n + 1 / 2,那么剩下的随便放,都不相邻

如果出现的数字次数小于 n + 1 / 2,那更不可能相邻了,如果有相邻的说明这个数字出现的次数一定比 这个数字出现的次数多,那它就是最多出现次数的数字了,所以先放次数最多的,放下的数字的顺序怎么放都可以。

代码

class Solution {
public:vector<int> rearrangeBarcodes(vector<int>& barcodes) {unordered_map<int, int> hash;int n = barcodes.size();int max_val = 0, max_count = 0;for(auto x : barcodes){if(max_count < ++hash[x]){max_val = x;max_count = hash[x];}}vector<int> ret(n);int index = 0;//先放出现次数最多的数字for(int i = 0; i < max_count; i++){ret[index] = max_val;index += 2;}//处理剩下的数字hash.erase(max_val);for(auto& [x, y] : hash){for(int i = 0; i < y; i++){if(index >= n)index = 1;ret[index] = x;index += 2;}}return ret;}
};

重构字符串

image-20240326203040064

代码

这道题目和上一题的区别就是这道题目可能是没有解的。

class Solution {
public:string reorganizeString(string s) {int hash[26] = {0};int n = s.size();char max_ch = ' ';int max_count = 0;for(const auto ch : s){if(max_count < ++hash[ch - 'a']){max_count = hash[ch - 'a'];max_ch = ch;}}if(max_count > (n + 1) / 2 ) return "";string ret(n, ' ');int index = 0;//先放最多的英文for(int i = 0; i < max_count; i++){ret[index] = max_ch;index += 2;}hash[max_ch - 'a'] = 0;//放剩下的英文for(int i = 0; i < 26; i++){for(int j = 0; j < hash[i]; j++){if(index >= n) index = 1;ret[index] = 'a' + i;index += 2;}}return ret;}
};

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

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

相关文章

苹果App Store上架工具介绍

文章目录 摘要引言正文1. Xcode2. [appuploder](https://www.applicationloader.net/)3. [克魔助手](https://keymob.com/) 4.[ipa guard](https://www.ipaguard.com/)总结参考资料 摘要 苹果App Store作为iOS应用程序的主要分发渠道&#xff0c;上架应用程序需要遵守规定和通…

云之道2024最新知识付费v2 3.1.1独立版小程序源码,带教程

事先声明&#xff1a;源码中存在引流的地方我全部都进行了修改&#xff0c;如果有没删到位的&#xff0c;烦请大佬留言告诉我&#xff01;本源码仅供学习使用&#xff0c;请在下载后的24小时内删除&#xff01; 下载链接&#xff1a;云之道知识付费v2 3.1.1独立版小程序源码&am…

FlorisBoard:Android开源键盘的现代化选择

FlorisBoard&#xff1a;Android开源键盘的现代化选择 简介 FlorisBoard是一款免费且开源的安卓键盘&#xff0c;适用于Android 7.0及以上版本的设备。它的现代化设计和用户友好的界面使其在众多键盘应用中脱颖而出。FlorisBoard的独特之处在于它注重用户体验的同时&#xff0…

【小白向】MAC端VSCode C++环境配置(超干货、超详细)

提示&#xff1a;使用环境为 MAC&#xff08;M2&#xff09; 其实 VSCode 很早就下载好了&#xff0c;但是因为在配置过程中总是遇到很多坑&#xff0c;搁置了很久&#xff0c;回头捡起遇到报 Error 还是两眼抓瞎&#xff0c;到处翻 blog。为了减少以后的遇坑可能性&#xff0c…

Grafana生成免登录查看的图表

1、创建Grafana组织 登录可观测可视化 Grafana 版控制台&#xff0c;在左侧导航栏单击工作区管理。在工作区管理页面&#xff0c;单击目标工作区右侧的访问地址url链接进入Grafana。 在Grafana左侧导航栏单击盾牌图标图标&#xff0c;然后单击Orgs页签。 在Orgs页签单击New or…

【分享贴】多项目并行,如何做好项目管理?

对于项目经理来说&#xff0c;多项目并行管理是工作中的常态&#xff0c;也是一大难点。当多个项目共同推进时&#xff0c;项目经理经常会出现手忙脚乱、四处救火的情形&#xff0c;例如&#xff1a; A.资源管理难&#xff1a;资源冲突、资源分配不合理会导致项目延期。 B.进度…

spring中,为什么前端明明传了值,后端却接收不到

文章目录 问题场景问题重现解决方式原因分析原理分析结论扩展 问题场景 在进行前后端的联调时&#xff0c;有时候会出现&#xff0c;前端明明传了值&#xff0c;后端接口却接收不到的情况&#xff0c;这种情况常常让人很苦恼&#xff0c;然后就会去仔细对比前后端的参数单词是…

华为数通方向HCIP-DataCom H12-821题库(多选题:201-220)

第201题 以下关于BGP中Orginator ID属性的描述,正确的是哪些项? A、Originator ID属于公认任意属性 B、当其他BGP Speaker接收到这条路由的时候,将比较收到的0nginator ID和本地的Router ID,如果两个ID相同BGP Speaker会忽略掉这条路由,不做处理 C、当一条路由第一次被RR…

深度学习基础入门:从数学到实现

I. 引言 A. 深度学习的背景 深度学习是机器学习的一个重要分支&#xff0c;是一种基于神经网络的算法&#xff0c;被广泛应用于计算机视觉、自然语言处理、语音识别等领域。与传统机器学习算法相比&#xff0c;深度学习具有更高的容错性、复杂性和精度&#xff0c;需要庞大的…

短信系统后台搭建要注意什么|网页版短信平台开发

在搭建短信系统后台时&#xff0c;需要注意以下几个关键方面&#xff0c;以确保系统的稳定性、安全性和高效性&#xff1a; 选择合适的技术栈&#xff1a;根据项目需求和团队实际情况选择合适的后端开发语言和框架&#xff0c;如Java Spring、Node.js、Python Django等。 系统…

数字化转型核心:实现业务与技术深度融合的运维数字化管理之道

写在前面 数字化转型已经成为大势所趋&#xff0c;各行各业正朝着数字化方向转型&#xff0c;利用数字化转型方法论和前沿科学技术实现降本、提质、增效&#xff0c;从而提升竞争力。 数字化转型是一项长期工作&#xff0c;包含的要素非常丰富&#xff0c;如数字化转型顶层设…

输入与输出

输入(Scanner类) Scanner是java5的新特性&#xff0c;在java.util包里&#xff0c;可以完成用户输入。步骤&#xff1a; 导入java.util包&#xff1b;构造Scanner对象&#xff0c;参数为u标准输入流System.in&#xff1b;使用next()方法系列接收数据 nextBoolean()接收一个布…