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

【算法】C++贪心算法解题(单调递增数字、坏了的计算器、合并区间)

文章目录

  • 前言
  • 算法题
    • 1.单调递增的数字
    • 2.坏了的计算器
    • 3.合并区间

前言

关于贪心算法/策略的概念、理解性问题在:

【算法】贪心算法解析:基本概念、策略证明与代码例题演示


算法题

1.单调递增的数字

在这里插入图片描述


思路

题目要求:找到 满足单调递增的 <= n的最大数字;

比如:

  • n = 1330, ret = 1229

  • n = 241, ret = 239

  • n = 1001, ret = 0999 -> 999

  • n = 233, ret = 233

    • 不难看出来,当n的位数第一次出现递减时,ret 的该位应该降位;
    • 但降位之前应该确保n的递减位前面没有值相同的,所以应该先向前检索

则总结出思路:

  1. 首先找出首个递减的位置: while(i + 1 < m && s[i] <= s[i+1]) i++;
  2. 随后判断递减位置之前,是否存在连续相同的数:while(i - 1 >= 0 && s[i] == s[i-1]) i--;
  3. 随后递减位-1,将后面的所有数位填9,即为最大的。

代码

class Solution {
public:int monotoneIncreasingDigits(int n) {string s = to_string(n);int i = 0, m = s.size();// 找第一个递减的位置while(i + 1 < m && s[i] <= s[i+1]) i++;// n 本身就是递增数if(i + 1 == m) return n;// 如果在首位递减的数 有连续相同的:回推while(i - 1 >= 0 && s[i] == s[i-1]) i--;// 递减位-1,后面全填9s[i]--;for(int j = i + 1; j < m; ++j) s[j] = '9';return stoi(s);}
};

2.坏了的计算器

在这里插入图片描述

思路

target 回溯到 startValue,以找到最小操作数:

  1. 回溯操作

    • 如果 target 大于 startValue
      • 如果 target 是偶数,将 target 除以 2。
      • 如果 target 是奇数,将 target 加 1(使其变为偶数,以便下一步除以 2)。
    • 每次操作计数 ret 加 1。
  2. 处理剩余部分

    • target 小于或等于 startValue 时,将 startValue 减去 target 并加到 ret 中,这部分是直接的加法操作。

最终返回 ret 加上 startValuetarget 之间的差值,即 startValue - target


代码

class Solution {
public:int brokenCalc(int startValue, int target) {// 正难则反:从target -> startValue 的最小操作数int ret = 0;while(target > startValue){if(target % 2 == 0) // 偶数除以2target /= 2;else // 奇数+1target += 1; ret++;}return ret + startValue - target;}
};

3.合并区间

在这里插入图片描述
思路

  1. 排序

    • 按照每个区间的左端点进行排序,以确保处理区间时按顺序考虑它们的重叠情况。
  2. 初始化

    • 设置初始区间的左端点 left 和右端点 right 为第一个区间的端点。
  3. 遍历和合并

    • 从第二个区间开始,遍历所有区间。
    • 对于每个区间,检查它的左端点是否小于或等于当前的右端点:
      • 如果是,说明区间有重叠,更新右端点为当前区间的右端点和之前右端点中的最大值。
      • 如果不是,说明区间不重叠,将当前区间 [left, right] 添加到结果中,并更新 leftright 为当前区间的端点。
  4. 添加最后一个区间

    • 遍历完成后,将最后的区间 [left, right] 添加到结果中。

代码

class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {// 以左端点排序sort(intervals.begin(), intervals.end());// 首区间的左右端点int left = intervals[0][0], right = intervals[0][1];vector<vector<int>> ret;for(int i = 1; i < intervals.size(); ++i){// 并集// 两个区间的左右端点int a = intervals[i][0], b = intervals[i][1];if(a <= right) { // 有重叠right = max(right, b);} else { // 无重叠ret.push_back({left, right});left = a, right = b;}}ret.push_back({left, right}); // 最后一个区间return ret;}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • PostgreSQL 中的 `generate_series` 函数使用
  • MAT:一款针对MSSQL服务器的安全检测与审计工具
  • 【C++】C++智能指针详解
  • VUE3 使用 <transition> 实现组件切换的过渡效果
  • 【日常记录-Linux】WebDriver
  • 如何打造抗冲击的超级电容器?用啥材料好?
  • 大数据技术概述
  • U盘常规数据恢复深度解析:原因、方案与预防策略
  • 文件包含PHP伪协议利用方法
  • c++(list)
  • CSS学习4[重点]
  • 原油市场“闪崩”,国际油价单日下跌超4%!
  • 一. 从Hive开始
  • 坑——fastjson将字符串转到带枚举的java对象
  • 【多线程】阻塞,忙等待,睡眠,挂起的简单理解,以及各自优缺点
  • [笔记] php常见简单功能及函数
  • 〔开发系列〕一次关于小程序开发的深度总结
  • Angular4 模板式表单用法以及验证
  • CODING 缺陷管理功能正式开始公测
  • Leetcode 27 Remove Element
  • Octave 入门
  • Python_网络编程
  • Redis学习笔记 - pipline(流水线、管道)
  • Swift 中的尾递归和蹦床
  • Vue学习第二天
  • 爱情 北京女病人
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 从0实现一个tiny react(三)生命周期
  • 复杂数据处理
  • 使用权重正则化较少模型过拟合
  • 首页查询功能的一次实现过程
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​比特币大跌的 2 个原因
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • $(selector).each()和$.each()的区别
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (二)学习JVM —— 垃圾回收机制
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (全注解开发)学习Spring-MVC的第三天
  • (数据大屏)(Hadoop)基于SSM框架的学院校友管理系统的设计与实现+文档
  • (五)MySQL的备份及恢复
  • (一)Java算法:二分查找
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • /dev/sda2 is mounted; will not make a filesystem here!
  • /proc/stat文件详解(翻译)
  • @ModelAttribute使用详解
  • @RequestBody与@RequestParam:Spring MVC中的参数接收差异解析
  • [《百万宝贝》观后]To be or not to be?
  • [20170705]lsnrctl status LISTENER_SCAN1
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略
  • [AIGC] MySQL存储引擎详解
  • [autojs]autojs开关按钮的简单使用
  • [BUUCTF]-Reverse:reverse3解析
  • [BZOJ] 2427: [HAOI2010]软件安装