贪心算法题目总结

1. 整数替换

看到这道题目,我们首先能想到的方法就应该是递归解法,我们来画个图

此时我们出现了重复的子问题,就可以使用递归,只要我们遇到偶数,直接将n除以2递归下去,如果是奇数,选出加1和减1中最小步数的那个继续递归下去即可,直接看代码:

class Solution {
public:int integerReplacement(int n) {if(n == 1)return 0;if(n & 1 == 1) // 奇数return min(integerReplacement(n+1),integerReplacement(n-1)) + 1;elsereturn integerReplacement(n / 2) + 1;}
};

然后我们去运行代码,很遗憾,此时代码没有通过,这是因为的递归过程中出现了大量的重复子问题的,这些重复的子问题其实我们已经计算过了,没必要再计算一次,所以我们可以利用记忆化搜索的备忘录来解决这个问题,此时我们递归的时候,如果此时备忘录立马存在这个值,我们就可以直接返回,如果没有这个值,我们再去递归。

class Solution {unordered_map<int,int> hash;
public:int integerReplacement(int n) {// 先判断是否再在备忘录中if(hash.count(n)) {return hash[n];} if(n == 1){hash[1] = 0;return 0;}  if(n & 1 == 1) // 奇数{hash[n] = min(integerReplacement(n+1),integerReplacement(n-1)) + 1;return hash[n];}else{hash[n] = integerReplacement(n / 2) + 1;return hash[n];}  }
};

但是此时我们发现程序没有通过,通过这个测试案例我们可以知道,当n是2147483647的时候,此时是奇数,会去递归2147483647+1,此时就超过了int的范围。

此时我们需要自己来定义一个dfs函数来解决这个问题。

class Solution {unordered_map<int,int> hash;
public:int integerReplacement(int n) {return dfs(n);}int dfs(long long int n){// 先判断是否再在备忘录中if(hash.count(n)) {return hash[n];} if(n == 1){hash[1] = 0;return 0;}  if(n & 1 == 1) // 奇数{hash[n] = min(dfs(n+1),dfs(n-1)) + 1;return hash[n];}else{hash[n] = dfs(n / 2) + 1;return hash[n];}  }
};

此时我们的代码就能通过,我们再来写另一种解法。

直接上手代码:

class Solution {
public:int integerReplacement(int n) {return dfs(n);}int dfs(long long int n){if(n == 1)return 0;if(n % 2 == 0) // 偶数{return dfs(n/2) + 1;} else{if(n == 3){return dfs(n-1) + 1;}else if(n % 4 == 1){return dfs(n - 1) + 1;}else if(n % 4 == 3){return dfs(n + 1) + 1;}}// 这里有返回值是因为要让所有的路径都有返回值return 0;}
};

其实我们这里也可以不使用递归来解决这个题目。

class Solution {
public:int integerReplacement(int n) {int ret = 0;while(n > 1){if(n % 2 == 0) // 偶数{n /= 2;ret++;}else // 奇数{if(n == 3){n = 1;ret += 2;}else if(n % 4 == 1){n -= 1;n /= 2;ret += 2;}else if(n % 4 == 3){n /= 2; // 这里需要先除2,防止n+1溢出n += 1;ret += 2;}}}return ret;}
};

2. 俄罗斯套娃信封问题

首先我们看到这个题目,就和我们之前的最长递增子序列是一样的,我们需要对左端点进行排序,然后看是否满足俄罗斯套娃的条件,既然是找最长的套娃个数,此时我们可以使用动态规划来解决这个问题,我们可以假设dp[i]位置表示i位置之前的此时最长的套娃个数,当我们到i的位置的时候,我们需要看看0到i-1位置的最长的套娃个数,如果有一个条件满足俄罗斯套娃的条件,那么最长的套娃个数就可以+1,此时就可以使用动态规划来解决这个问题。

class Solution {
public:int maxEnvelopes(vector<vector<int>>& envelopes) {// 动态规划sort(envelopes.begin(), envelopes.end());int n = envelopes.size();vector<int> dp(n, 1);int ret = 1;for(int i = 1; i < n; i++){   for(int j = 0; j < i; j++){if(envelopes[i][0] > envelopes[j][0] &&envelopes[i][1] > envelopes[j][1]){dp[i] = max(dp[i], dp[j]) + 1;}}ret = max(ret, dp[i]);}return ret;}
};

但是此时我们的代码会超时,所以此时我们就需要来使用另一种策略

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 b = envelopes[i][1];if(b > ret.back()){ret.push_back(b);}else{int left = 0, right = ret.size() - 1;while(left < right){int mid = (left + right) / 2;if(ret[mid] >= b) right = mid;else left = mid + 1;}ret[left] = b;}}return ret.size(); }
};

3. 可被三整除的最大和

正难则反: 我们可以先把所有的数累加在⼀起,然后根据累加和的结果,贪心的删除⼀些数。

那么我们该如何寻找到最小的和次小的值呢?当然我们可以进行一下sort排序取出最小的和次小的值,但是我们知道sort的底层使用的是快速排序,时间复杂度是O(N*logN),所以此时并不是最优的选择,我们可以使用O(N)的时间复杂度来解决这个问题:

class Solution {
public:int maxSumDivThree(vector<int>& nums) {int x1 = 0x3f3f3f3f3f;int x2 = 0x3f3f3f3f3f;int y1 = 0x3f3f3f3f3f;int y2 = 0x3f3f3f3f3f;int sum = 0;// 求出总和,最小和次小的值for(int i = 0; i < nums.size(); i++){sum += nums[i];if(nums[i] % 3 == 1) // 判断当值余数是否为1{if(nums[i] <= x1)x2 = x1, x1 = nums[i];else if(nums[i] > x1 && nums[i] < x2)x2 = nums[i];}else if(nums[i] % 3 == 2) // 判断当值余数是否为2{if(nums[i] <= y1)y2 = y1, y1 = nums[i];else if(nums[i] > y1 && nums[i] < y2)y2 = nums[i];}}// 分类讨论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);}
};

4. 距离相等的条形码

这道题目比较简单,我们只需要每次处理一批相同的数字,往 n 个空里面摆放; 每次摆放的时候,隔一个格子摆放一个数,但是我们需要优先处理出现次数最多的那个数,其余的数处理的顺序就没什么要求了。

class Solution {
public:vector<int> rearrangeBarcodes(vector<int>& barcodes) {unordered_map<int, int> hash; // 统计每个数出现的次数int maxVal = 0; // 最大的值int maxCount = 0; // 最大值的项数for(auto& e : barcodes){if(maxCount < ++hash[e]){maxCount = hash[e];maxVal = e;}}vector<int> v(barcodes.size(), 0);// 先处理出现次数最多的数int index = 0;for(int i = 0; i < maxCount; i++){v[index] = maxVal;index += 2;}// 处理剩下的数,不用管顺序,直接防即可hash.erase(maxVal);for(auto& [x, y] : hash){   for(int i = 0; i < y; i++){// 超过最大位置,需要重新从头开始摆放if(index >= barcodes.size()) index = 1;v[index] = x;index += 2;}}return v;}
};

5. 重构字符串

我们读完题目会发现这道题目和上一道题目是类似的,只不过上一道题目是重排数字,而这道题目是重排字符串,思路基本上都是一致的,但是上一个题目明确告诉了我们所有数字都是可以重排列的,但是我们这个题目不一定,因此我们需要先判断一下,如果出现最多的字符的个数大于(n + 1) / 2 就无法重排,其他情况下就可以直接重排列,那我们直接上代码啦!

class Solution {
public:string reorganizeString(string s) {unordered_map<char, int> hash;char maxVal = ' ';int maxCount = 0;for(auto& x : s){if(maxCount < ++hash[x]){maxCount = hash[x];maxVal = x;}}if(maxCount > ((s.size() + 1) / 2))return "";// 先处理出现次数最多的那个字符string ret;ret.resize(s.size());int index = 0;for(int i = 0; i < maxCount; i++){ret[index] = maxVal;index += 2;}hash.erase(maxVal); // 删除最多元素项的值// 处理剩余的值for(auto& [x, y] : hash){for(int i = 0; i < y; i++){if(index >= ret.size()) index = 1;ret[index] = x;index += 2;}}return ret;}
};

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

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

相关文章

我在手提电脑上将大模型训练成了语文老师

&#xff08;图片由大模型生成&#xff0c;如有侵权&#xff0c;立删&#xff09; 记得一年多以前&#xff0c;和不少商家交流大模型解决方案时&#xff0c;他们谈到内部有很多的资料&#xff0c;可以对大模型进行训练&#xff0c;让大模型变得更有智慧&#xff0c;从而为客户…

Day9:逆波兰表达式求值150 滑动窗口最大值239 前 K 个高频元素347

题目150. 逆波兰表达式求值 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int evalRPN(vector<string>& tokens) {//使用栈来消除stack<string> st;for(int i0;i<tokens.size();i){if(tokens[i]""||tokens[i]"-"|…

创新赋能,高效二开!CRMEB 标准版 v5.4公测版发布

历经十年磨砺&#xff0c;CRMEB 标准版如今已成为众多技术开发者与企业二次开发、构建定制化项目的热门系统&#xff0c;其全开源无加密、功能齐全、独立部署的特质&#xff0c;造就了标准版系统方便二开的优势&#xff0c;不仅深受开发者喜爱&#xff0c;更因其实用性和可靠性…

运行vue : 无法加载文件 C:\Program Files\nodejs\node_global\vue.ps1,因为在此系统上禁止运行脚本。

报错背景: 重装了win10系统,然后准备安装Vue,这个时候我已经安装好了node.js和npm,输入node -v和npm -v都有正确输出,但是每次输入npm install -g vue/cli 安装的时候,就会报错. 大家安装node.js的时候最好就是默认路径(C:\Program Files\nodejs),别去修改不然很多报错.(个人…

Linux Centos7部署Zookeeper

目录 一、下载zookeeper 二、单机部署 1、创建目录 2、解压 3、修改配置文件名 ​4、创建保存数据的文件夹 ​5、修改配置文件保存数据的地址 ​6、启动服务 7、api创建节点 一、下载zookeeper 地址&#xff1a;Index of /dist/zookeeper/zookeeper-3.5.7 (apache.org…

名企面试必问30题(十五)——你的学历有点低,你怎么看?

1.思路 首先承认学历低这一事实&#xff1a;我坦诚地承认自己的学历相对较低。 后续解决方案&#xff1a;不过&#xff0c;我相信能力的展现不仅仅取决于学历。在过往的工作经历中&#xff0c;我积累了丰富的实践经验&#xff0c;培养了较强的学习能力和解决问题的能力。我会持…

两台电脑怎么传文件?干货分享教程

当需要在两台电脑之间传输文件时&#xff0c;有多种方便的方法可供选择&#xff0c;以下是一些常见的方式及教程&#xff1a; 使用局域网共享&#xff1a; 确保两台电脑连接在同一个局域网内。 在其中一台电脑上&#xff0c;设置要共享的文件夹。右键点击文件夹&#xff0c;选…

论文学习——使用基于多项式拟合的预测算法求解动态多目标问题

论文题目&#xff1a;Solving dynamic multi-objective problems using polynomial fitting-based prediction algorithm 使用基于多项式拟合的预测算法求解动态多目标问题&#xff08;Qingyang Zhang , Xiangyu He,Shengxiang Yang , Yongquan Dong , Hui Song , Shouyong Ji…

归并排序-MergeSort (C语言详解)

目录 前言归并排序的思想归并排序的递归法归并排序的非递归法归并排序的时间复杂度与适用场景总结 前言 好久不见, 前面我们了解到了快速排序, 那么本篇旨在介绍另外一种排序, 它和快速排序的思想雷同, 但又有区别, 这就是归并排序, 如下图, 我们对比快速排序与归并排序. 本…

Nacos配置中心客户端源码分析(二): 客户端和服务端交互

本文收录于专栏 Nacos 推荐阅读&#xff1a;Nacos 架构 & 原理 ⚠️&#xff1a;使用的Nacos版本为2.3.X 文章目录 前言一、NacosConfigLoader二、NacosConfigService三、ClientWorker四、服务端处理逻辑总结 前言 上篇文章我们简单看了看Nacos客户端在启动的时候&#xf…

远程抄表管理系统建设方案(Word原件)

远程抄表管理系统建设方案应涵盖智能表计安装、数据采集与传输、数据处理与分析三大核心环节。首先&#xff0c;安装智能表计以实时采集水、电、气等数据&#xff1b;其次&#xff0c;利用先进的通信技术&#xff08;如GPRS、LoRa等&#xff09;实现数据的稳定传输&#xff1b;…

c语言回顾-数组(全网最详细,哈哈哈)

目录 前言&#xff0c;和小编一起感受数组的魅力&#xff01;&#xff01;&#xff01; 1.数组的概念 2.一维数组的创建和初始化 2.1数组创建 2.2数组的初始化 2.3数组的类型 3.一维数组的使用 3.1数组下标 3.2数组元素的输入输出 小结&#xff1a; 4.一维数组在内存…

pycharm的usages在哪设置?

参考文章&#xff1a;https://blog.51cto.com/save/8961821 在代码编辑器&#xff08;如PyCharm或IntelliJ IDEA&#xff09;中&#xff0c;"1 usage"通常表示当前光标所在的代码元素&#xff08;如变量、函数、类等&#xff09;在其他地方被使用了一次。这个功能可…

什么是自动气象站呢

自动气象站&#xff0c;作为现代气象观测的重要工具&#xff0c;已经深入到我们生活的各个领域&#xff0c;从气象预报到农业生产&#xff0c;再到环境保护&#xff0c;自动气象站都发挥着不可或缺的作用。 自动气象站&#xff0c;顾名思义&#xff0c;是一种能够自动收集、处理…

昇思25天学习打卡营第7天|网络构建

网络构建 神经网络模型由tensor操作和神经网络层构成。 MIndSporezhong&#xff0c;Cell是构建所有网络的基类&#xff0c;也是网络的基本单元。cell也由子cell构成。 定义模型类 # 继承nn.Cell类 class Network(nn.Cell):def __init__(self):super().__init__()self.flatte…

所以,这些AI产品都死了?? 创业就是一场大型狼人杀;独立开发者的营销流量密码;谷歌竟然搞砸过300个项目 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;ShowMeAI官网 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; 1. 你可能不知道&#xff1a;Google Graveyard「埋葬」着 300 个被谷歌搞砸的项目 官网链接 → https://killedbygoogle.com Google Graveyard (Killed by Google…

【课程设计】基于python的一款简单的计算器

我们是大二本科生团队&#xff0c;主力两人耗时3天完成了这款计算器的制作。希望大家给我们多多引流&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 欢迎各位优秀的高考学子报考长安大学&#xff0c;报考长安大学电子信息工程专业。 欢迎有志于就…

游戏冻结工具 -- 雪藏HsFreezer v1.78

软件简介 HsFreezer是一款多功能游戏冻结工具&#xff0c;它允许用户随意暂停和继续游戏&#xff0c;同时具备系统优化和进程管理的功能。这款软件特别适合希望在游戏加载时间节省或在游戏与其他任务之间快速切换的用户。其主要特点包括快捷键操作、单锁模式的丝滑切换&#x…

音乐播放器小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;歌曲信息管理&#xff0c;会员优惠管理&#xff0c;用户管理&#xff0c;会员办理管理&#xff0c;歌曲分类管理&#xff0c;会员信息管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;歌曲信…

人工智能--图像语义分割

个人主页&#xff1a;欢迎来到 Papicatch的博客 课设专栏 &#xff1a;学生成绩管理系统 专业知识专栏&#xff1a;专业知识 ​ 文章目录 &#x1f349;引言 &#x1f349;介绍 &#x1f348;工作原理 &#x1f34d;数据准备 &#x1f34d;特征提取 &#x1f34d;像素分…