贪心算法专题(四)

目录

1. 单调递增的数字

1.1 算法原理 

1.2 算法代码

2. 坏了的计算器

2.1 算法原理

2.2 算法代码

3. 合并区间

3.1 算法原理

3.2 算法代码

4. 无重叠区间

4.1 算法原理

4.2 算法代码

5. 用最少数量的箭引爆气球

5.1 算法原理

​5.2 算法代码


1. 单调递增的数字

738. 单调递增的数字 - 力扣(LeetCode)

1.1 算法原理 

解法一: 暴力枚举

依次比较每个位上的值, 观察是否递增, 一旦发现不是递增的, 则 num--, 继续比较.
比较时, 有以下两种方式:

  1. 将数字封装成字符串, 依次比较每个位上的值
  2. 以 "%10 , /10" 的顺序, 依次比较每个位上的值

解法二: 贪心

  • 即从左往右, 找到第一个递减的位置后, 向前推, 定位到相同区域的最左端, 使其减小 1, 后面的位置全部置为 '9'

1.2 算法代码

class Solution {
    public int monotoneIncreasingDigits(int n) {
        String s = String.valueOf(n);
        char[] ch = s.toCharArray();
        int len = ch.length, i = 0;
        // 找到第一个递减的位置
        while(i + 1 < len && ch[i + 1] >= ch[i]) i++;
        // 特殊情况 => 本来就是递增的
        if(i == len - 1) return n;
        // 从这个位置向前推, 找到相同区域的最左端
        while(i - 1 >= 0 && ch[i - 1] == ch[i]) i--;
        ch[i]--;
        for(int j = i + 1; j < len; j++) ch[j] = '9';

        //while(s.charAt(0) == '0') s = s.substring(1, s.length());
        // parseInt 方法自动屏蔽掉最左端的 0
        return Integer.parseInt(new String(ch));
    }
    /**
     * 暴力枚举 => 通过字符串比较
     * @param n
     * @return
     */
    public int monotoneIncreasingDigits1(int n) {
        String s = String.valueOf(n);
        char[] ch = s.toCharArray();
        int len = ch.length;
        for(int i = 0; i < len; i++) {
            if(i + 1 < len && ch[i] > ch[i + 1]) {
                int num = Integer.parseInt(s) - 1;
                s = String.valueOf(num);
                ch = s.toCharArray();
                len = ch.length;
                i = -1;
            }
        }
        return Integer.parseInt(s);
    }
}

2. 坏了的计算器

991. 坏了的计算器 - 力扣(LeetCode)

2.1 算法原理

如果要将 start => target, 需要考虑什么时候 -1, 什么时候 *2, 在这两个操作间选出最优的方案, 但是这样处理是很麻烦的. 所以, 我们采用正难则反的思想, target => start, 此时只有 +1 和 /2 两个操作:

这里, 我们需要根据 target 的数值, 进行分类讨论:

  • 当 target <= start 时, 只有 +1 可以到达, return start - target;

接着, 根据 target 的奇偶性, 进行分类讨论:

  1. target 为奇数时, 只能进行 +1 操作(除法会使数据丢失)
  2. target 为偶数时, 进行 /2 操作(贪心: /2 操作优于 +1 操作)

当 target 为偶数时, 此时使用了贪心策略: /2 优于 +1, 证明如下:

2.2 算法代码

class Solution {
    public int brokenCalc(int startValue, int target) {
        // 正难则反: target => startValue,  /2 或者 +1
        int ret = 0;
        while(target != startValue) {
            if(target <= startValue) return ret + startValue - target;
            if(target % 2 != 0) target += 1;// 奇数时, 只能 +
            else target /= 2;// 偶数时: 贪心: / 优于 +
            ret++;
        }
        return ret;
    }
}

3. 合并区间

56. 合并区间 - 力扣(LeetCode)

3.1 算法原理

  • 合并区间, 本质: 求并集

解法: 排序 + 贪心

  1. 排序: 根据左端点或者右端点进行排序(本题以左端点进行排序), 排完序后, 能够合并的区间, 一定是相邻的.
  2. 贪心: 合并 => 求并集, 根据当前区间右端点的值, 以及相邻区间左端点的值, 判断两个区间是否能合并(有没有重叠部分).

3.2 算法代码

class Solution {
    public int[][] merge(int[][] intervals) {
        List<int[]> list = new ArrayList<>();
        // 1. 排序(左端点)
        Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
        int left = intervals[0][0], right = intervals[0][1], n = intervals.length;
        for (int i = 1; i < n; i++) {
            if (intervals[i][0] <= right) { 
                // 有重叠部分 => 可以合并, 求并集
                right = Math.max(right, intervals[i][1]);
            } else { 
                // 不能合并 => 加入结果中
                list.add(new int[]{left, right});
                left = intervals[i][0];
                right = intervals[i][1];
            }
        }
        // 此时, 最后一个区间还没有加入结果中
        list.add(new int[]{left, right});
        // int[][] ret = new int[list.size()][2];
        // for(int i = 0; i < list.size(); i++) {
        //     int j = 0;
        //     for(int x : list.get(i)) ret[i][j++] = x;
        // }
        
        // toArray: 集合转化为数组
        // 参数: new int[0][] => 生成的数值不限行, 不限列, 有多少放多少
        return list.toArray(new int[0][]);
    }
}

4. 无重叠区间

435. 无重叠区间 - 力扣(LeetCode)

4.1 算法原理

本题的核心思想和上一题其实是一致的.
 解法: 排序 + 贪心

  • 排序: 根据左端点进行排序

排序后, 如果相邻的两个区间没有重叠, 那么不需要移除; 如果有重叠, 则必须移除一个!!
(注意, 本题与上题不同, 两端点相同时, 视为无重叠)

  • 贪心: 移除区间较大的那一个, 保留区间较小的那一个(根据两区间右端点的大小进行判断)

4.2 算法代码

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        // 1. 排序(左端点)
        Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
        int ret = 0, right = intervals[0][1];
        // 2. 移除区间
        for(int i = 1; i < intervals.length; i++) {
            int a = intervals[i][0], b = intervals[i][1];
            if(a < right) {
                // 有重叠区间, 舍弃一个
                // 贪心 => 保留小区间, 舍弃大区间
                right = Math.min(right, b);
                ret++;
            }else {
                // 无重叠区间, 更新 right
                right = b;
            }
        }
        return ret;
    }
}

5. 用最少数量的箭引爆气球

452. 用最少数量的箭引爆气球 - 力扣(LeetCode)

5.1 算法原理

解法: 排序 + 贪心

  • 排序: 对左端点进行排序 => 互相重叠的区间是连续的
  • 贪心: 使用最少数量的箭, 即找到互相重叠区间的数量(求交集)

5.2 算法代码

class Solution {
    public int findMinArrowShots(int[][] points) {
        // 排序(左端点)
        Arrays.sort(points, (a, b) -> a[0] > b[0] ? 1 : -1);
        int ret = 0, right = points[0][1];
        int n = points.length;
        // 求出互相重叠区间的数量
        for(int i = 1; i < n; i++) {
            int a = points[i][0], b = points[i][1];
            if(a <= right) {
                // 有重叠
                right = Math.min(right, b);
            }else {
                // 无重叠
                ret++;
                right = b;
            }
        }
        return ret + 1;
    }
}

END

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IAR环境下的FlashLoader设计

目录 1.为什么要Flash Loader 2.Flash Loader设计细节 2.1 简单的代码框架 2.2 迷人的宏使用 2.3 关键的配置文件 3.dmac和mac文件 4.小结 搞国产车规芯片&#xff0c;IAR是必不可少的编译调试集成工具&#xff0c;历史背景不赘述&#xff0c;今天主要聊聊基于IAR的Fla…

一些硬件知识【2024/12/6】

MP6924A: 正点原子加热台拆解&#xff1a; PMOS 相比 NMOS 的缺点&#xff1a; 缺点描述迁移率低PMOS 中的空穴迁移率约为电子迁移率的 1/3 到 1/2&#xff0c;导致导通电流较低。开关速度慢由于迁移率较低&#xff0c;PMOS 的开关速度比 NMOS 慢&#xff0c;不适合高速数字电…

在本地运行大语言模型

1&#xff0c;打开下面网站下载&#xff0c;软件 lm studio 2&#xff0c; 设置模型下载路径 3&#xff0c;没有魔法条件的人&#xff0c;去镜像网站下载模型的镜像文件 、 4&#xff0c;

【单片机】ESP32-S3+多TMC2209控制步进电机系列3 使用TMC2209库实现UART通讯

目录 1.下载TMC2209.h库2.代码部分3.效果展示 1.下载TMC2209.h库 在Arudino环境中&#xff0c;有两个不错的库可以驱动TMC2209。 TMC2209库TMCStepper库 TMC2209库只针对TMC2209驱动器&#xff0c;而TMCStepper库除了能够支持TMC2209驱动器&#xff0c;还能够支持其他TMC的驱…

【服务器部署应用由http协议切换为https】

文章目录 服务器部署应用由http协议切换为https1. 下载openssl及其配置1.1 下载1.2 无脑下一步即可1.3 环境变量配置1.4 验证配置以及生成证书证书路径 2. nginx配置修改 服务器部署应用由http协议切换为https 1. 下载openssl及其配置 1.1 下载 openssl下载地址 根据系统选择…

Linux——管理用户和用户组

一、用户有哪些 root用户 定义&#xff1a;root用户是Linux系统中的最高权限用户&#xff0c;具有对系统所有资源的完全控制权。特性&#xff1a;root用户可以执行系统中的任何操作&#xff0c;包括修改系统配置文件、安装软件、管理系统服务等。由于其拥有最高权限&#xff0c…

synchronized的特性

1.互斥 对于synchronized修饰的方法及代码块不同线程想同时进行访问就会互斥。 就比如synchronized修饰代码块时&#xff0c;一个线程进入该代码块就会进行“加锁”。 退出代码块时会进行“解锁”。 当其他线程想要访问被加锁的代码块时&#xff0c;就会阻塞等待。 阻塞等待…

如何在树莓派上安装Arduino IDE

git clone https://github.com/JetsonHacksNano/installArduinoIDE.git cd installArduinoIDE ./installArduinoIDE.sh sudo reboot sudo shutdown -h now

【JAVA项目】基于ssm的【汽车在线销售系统】

【JAVA项目】基于ssm的【汽车在线销售系统】 技术简介&#xff1a;采用JSP技术、B/S架构、SSM框架、MySQL技术等实现。 系统简介&#xff1a;首页汽车在线销售系统模块如下&#xff1a;首页、汽车信息、新闻资讯、留言反馈、我的收藏管理等功能。管理员输入个人的账号、密码登录…

【代码随想录】刷题记录(66)-修剪二叉搜索树

题目描述&#xff1a; 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果没有被移除&#xff0c;原有的父…

《蓝桥杯比赛规划》

大家好啊&#xff01;我是NiJiMingCheng 我的博客&#xff1a;NiJiMingCheng 这节课我们来分享蓝桥杯比赛规划&#xff0c;好的规划会给我们的学习带来良好的收益&#xff0c;废话少说接下来就让我们进入学习规划吧&#xff0c;加油哦&#xff01;&#xff01;&#xff01; 一、…

Vue3+Vite项目从零搭建+安装依赖+配置按需导入

环境准备 Vscode/HBuilder等任何一种前端开发工具node.js&npm本地开发环境 源代码管理&#xff1a;Git 技术栈 项目构建 创建项目 npm create vite 依次运行最后三行出现&#xff0c;成功启动项目 在浏览器输入 http://localhost:5173/ 可以显示页面 src别名的配置…

小程序维护外包流程和费用

由于某些原因很多老板想要跟换掉小程序原来合作的开发公司&#xff0c;重新把小程序系统维护外包新的公司。小程序系统外包维护是一个涉及多个方面的过程&#xff0c;需要从需求明确、选择团队到持续优化等多个环节进行细致管理。以下就是小程序系统外包维护主要包括几个关键步…

Meta Llama 3.3 70B:性能卓越且成本效益的新选择

Meta Llama 3.3 70B&#xff1a;性能卓越且成本效益的新选择 引言 在人工智能领域&#xff0c;大型语言模型一直是研究和应用的热点。Meta公司最近发布了其最新的Llama系列模型——Llama 3.3 70B&#xff0c;这是一个具有70亿参数的生成式AI模型&#xff0c;它在性能上与4050…

【数字图像处理】期末实验,基于直方图均衡化实验, 空间域图像增强, 数字图像傅里叶变化、频域图像处理,基于Hough变换的边缘检测

关注作者了解更多 我的其他CSDN专栏 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处理 光电融合集成电路…

01_Node.js入门 (黑马)

01_Node.js入门 知识点自测 从 index.js 出发&#xff0c;访问到 student/data.json 的相对路径如何写? A&#xff1a;../public/teacher/data.json B&#xff1a;./public/student/data.json C&#xff1a;../student/data.json <details><summary>答案</sum…

React第十七章(useRef)

useRef 当你在React中需要处理DOM元素或需要在组件渲染之间保持持久性数据时&#xff0c;便可以使用useRef。 import { useRef } from react; const refValue useRef(initialValue) refValue.current // 访问ref的值 类似于vue的ref,Vue的ref是.value&#xff0c;其次就是vu…

ThinkPHP知识库文档系统源码

知识库文档系统 一款基于ThinkPHP开发的知识库文档系统&#xff0c;可用于企业工作流程的文档管理&#xff0c;结构化记录沉淀高价值信息&#xff0c;形成完整的知识体系&#xff0c;能够轻松提升知识的流转和传播效率&#xff0c;更好地成就组织和个人。为部门、团队或项目搭…

TIM输入捕获---STM

一、简介 IC输入捕获 输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变时&#xff0c;当前CNT的值将被锁存在CCR中&#xff0c;可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数 每个高级定时器和通用定时器都拥有4个输入捕获通道 可配置为PWMI模…

Spring Data JPA 入门

文章目录 前言、Spring Data JPA 是什么&#xff1f;1、背景2、优势3、Spring Data JPA 和 MyBatis-Plus 对比4、Spring Data JPA 与 JPA 的关系是什么&#xff1f; 一、准备1、依赖引入Spring Boot 框架依赖引入&#xff1a;非 Spring Boot 框架依赖引入&#xff1a; 2、定义实…