Leetcode算法训练日记 | day37

专题九  贪心算法

一、单调递增的数字

1.题目

Leetcode:第 738 题

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。

示例 1:

输入: n = 10
输出: 9

示例 2:

输入: n = 1234
输出: 1234

示例 3:

输入: n = 332
输出: 299

2.解题思路

使用贪心算法解决单调递增的数字问题。

monotoneIncreasingDigits 函数中,首先将整数 N 转换为字符串 strNum。然后,我们使用两个 for 循环来找到并修改数字。第一个 for 循环从字符串的末尾开始向前遍历,寻找第一个不满足单调递增条件的位置。一旦找到这样的位置,我们记录下这个位置,并将其前一个位置的数字减 1,因为我们知道这个数字太大,导致无法通过简单地将后面的数字置为 9 来得到下一个更大的单调递增数字。第二个 for 循环从记录的位置开始,将后面的所有数字置为 9。这是因为在第一个 for 循环中,我们已经确保了前面的数字是单调递增的,所以我们只需要简单地增加后面的数字。最后,我们使用 stoi 函数将修改后的字符串 strNum 转换回整数,并返回这个新的整数。这个新的整数就是满足条件的下一个更大的单调递增数字。

3.实现代码

#include <iostream>
#include <vector>
#include <string>
using namespace std;class Solution {
public:// monotoneIncreasingDigits 函数用于找到一个数字 N 的下一个更大的单调递增数字int monotoneIncreasingDigits(int N) {// 将整数 N 转换为字符串,以便逐位操作string strNum = to_string(N);// 初始化 flag 变量,用于标记从哪个位置开始可以将数字置为 9// 默认设置为字符串的长度,即最开始不需要置任何数字为 9int flag = strNum.size();// 从字符串的末尾开始向前遍历,找到第一个不是严格递增的位置for (int i = strNum.size() - 1; i > 0; i--) {// 如果当前位的数字大于下一位,说明找到了一个递减的位置if (strNum[i - 1] > strNum[i]) {// 记录这个位置,从这个位置开始,可以置后面的所有数字为 9flag = i;// 将当前位置的数字减 1,因为当前位置的数字太大,导致后面的数字无法通过置为 9 来增加strNum[i - 1]--;}}// 从记录的位置开始,将后面的所有数字置为 9for (int i = flag; i < strNum.size(); i++) {strNum[i] = '9';}// 将修改后的字符串转换回整数,并返回return stoi(strNum);}
};//测试
int main()
{Solution p;int n = 1234;cout <<"n = " <<n<< endl;int result = p.monotoneIncreasingDigits(n);cout << "小于或等于 n 的最大数字:" << result << endl;cout << endl;return 0;
}

 

 

二、监控二叉树

1.题目

Leetcode:第 738 题

给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。

示例 1:

输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。

示例 2:

输入:[0,0,null,0,null,0,null,null,0]
输出:2
解释:需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。
2.解题思路

使用贪心算法解决监控二叉树问题。

minCameraCover 函数中,我们首先初始化 result 为 0,表示还没有放置任何摄像头。然后,我们调用 traversal 函数从根节点开始递归遍历二叉树。traversal 函数的返回值决定了当前节点及其子节点的覆盖状态。traversal 函数中,我们首先检查当前节点是否为空,如果为空,返回 2。然后,我们递归地遍历左子树和右子树,并获取它们的返回值。根据这些返回值,我们可以确定当前节点是否需要一个摄像头,以及如何继续递归地遍历子树。如果 traversal 函数返回 0,表示根节点及其子节点都被摄像头覆盖了,我们不需要在根节点放置摄像头。否则,我们需要在根节点放置一个摄像头,并增加 result 的值。最终,minCameraCover 函数返回 result,即覆盖整个二叉树所需的最小摄像头数量。

3.实现代码
#include <iostream>
#include <vector>
#include <string>
using namespace std;// 定义一个结构体TreeNode,用于表示二叉树的节点。
struct TreeNode {int val; // 存储节点的值。TreeNode* left; // 指向该节点左子树的指针。TreeNode* right; // 指向该节点右子树的指针。// TreeNode的构造函数,用于创建一个TreeNode实例。// 参数x是节点的值,left和right默认为NULL,表示没有左右子节点。TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};class Solution {
private:int result; // 用于存储最终的摄像头数量// traversal 函数用于递归遍历二叉树,返回值有特定的含义:// 返回 0 表示该节点及其子节点都不需要摄像头(叶子节点或其子节点都被摄像头覆盖)// 返回 1 表示该节点需要一个摄像头(其子节点都被摄像头覆盖)// 返回 2 表示该节点不需要摄像头,但其子节点需要摄像头int traversal(TreeNode* cur) {if (cur == NULL) return 2; // 如果当前节点为空,返回 2int left = traversal(cur->left);    // 递归遍历左子树,并获取返回值int right = traversal(cur->right);  // 递归遍历右子树,并获取返回值// 如果左右子树返回的值都是 2,说明当前节点不需要摄像头,其子节点也不需要if (left == 2 && right == 2) return 0;// 如果左子树或右子树返回的值是 0,说明该子树被摄像头覆盖,当前节点需要一个摄像头else if (left == 0 || right == 0) {result++; // 增加摄像头数量return 1; // 返回 1 表示当前节点需要一个摄像头}else return 2; // 如果到这里,说明当前节点的子节点都需要摄像头,当前节点也不需要}public:// minCameraCover 函数用于计算在二叉树上最小数量的摄像头以覆盖所有节点int minCameraCover(TreeNode* root) {result = 0; // 初始化摄像头数量为 0// 从根节点开始遍历二叉树if (traversal(root) == 0) { // 如果根节点返回 0,说明根节点无覆盖result++; // 根节点需要一个摄像头}return result; // 返回最终的摄像头数量}
};

ps:以上皆是本人在探索算法旅途中的浅薄见解,诚挚地希望得到各位的宝贵意见与悉心指导,若有不足或谬误之处,还请多多指教。 

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

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

相关文章

ProTable/EditableProTable修改表单保存后刷新界面数据不更新

1.背景 大坑。编辑表格保存后&#xff0c;接口拿到最新表格数据&#xff0c;但是界面没有刷新。本以为是加个id给表格就能刷新的&#xff0c;没想到需要重置表单。 2.解决 表格数据变更后需要重置表单 form.resetFields() <ProTablecolumns{columns}rowKey"id"…

面试:finalize

一、概述 将资源释放和清理放在finalize方法中非常不好&#xff0c;非常影响性能&#xff0c;严重时甚至会引起OOM&#xff08;Out Of Memory&#xff09;&#xff0c;从Java9开始就被标注为Deprecated&#xff0c;不建议被使用了。 二、两个重要的队列 1、unfinalized 队列 当…

React Router 6 + Ant Design:构建基于角色的动态路由和菜单

要根据用户的角色生成不同的路由菜单并实现权限控制,你可以采取以下步骤: 定义路由配置 首先,你需要定义一个包含所有可能路由的配置文件,例如: const routes [{path: /dashboard,element: <DashboardPage />,roles: [admin, manager, user]},{path: /users,element:…

Python 网络与并发编程(四)

文章目录 协程Coroutines协程的核心(控制流的让出和恢复)协程和多线程比较协程的优点协程的缺点 asyncio实现协程(重点) 协程Coroutines 协程&#xff0c;全称是“协同程序”&#xff0c;用来实现任务协作。是一种在线程中&#xff0c;比线程更加轻量级的存在&#xff0c;由程…

数据库并发控制思维导图+大纲笔记

思维导图 大纲笔记 多用户数据库系统 定义 允许多个用户同时使用的数据库系统特点 在同一时刻并发运行的事务数可达数百上千个多事务执行方式 事务串行执行交叉并发方式 单处理机系统同时并发方式 多处理机系统事务并发执行带来的问题 产生多个事务同时存取同一数据的情况可能…

自养号测评详解:成功助力亚马逊爆款必备手册

对于亚马逊商家而言&#xff0c;如何成功打造爆款产品无疑是他们日常运营中最为关注的核心议题。然而&#xff0c;尽管众多商家费尽心思去挑选和推广产品&#xff0c;但有时候却仍然难以选出真正的爆款。这不禁让人深思&#xff0c;究竟是什么原因导致商家在选品过程中屡屡碰壁…

微信小程序使用 Vant Weapp 中 Collapse 折叠面板 的问题!

需求&#xff1a;结合Tab 标签页 和 Collapse 折叠面板 组合成显示课本和章节内容&#xff0c;并且用户体验要好点&#xff01; 如下图展示&#xff1a; 问题&#xff1a;如何使用Collapse 折叠面板 将内容循环展示出来&#xff1f; js中的数据是这样的 代码实现&#xff1…

基于深度学习的实时人脸检测与情绪分类

情绪分类 实时人脸检测与情绪分类 Kaggle Competion 数据集 fer2013 中的测试准确率为 66%CK数据集的检验准确率为99.87%情绪分类器模型预测从网络摄像头捕获的实时视频中的平均成本时间为 4~ 10ms 关键技术要点&#xff1a; 实时人脸检测&#xff1a;系统采用了前沿的人脸检…

go语言并发实战——日志收集系统(九) 基于etcd的代码重构思考与初步实现

前言 在之前我们j基于sarama,tail还有go-ini实现了日志收集系统客户端的编写&#xff0c;但是我们梳理一下可以发现&#xff0c;该客户端还存在一些问题: 客户端一次只能读取一个日志文件&#xff0c;无法同时读取多个分区无法管理日志存放的分区(topic) 那我们一个如何去解决…

基于DEAP数据集的四种机器学习方法的情绪分类

在机器学习领域&#xff0c;KNN&#xff08;K-Nearest Neighbors&#xff09;、SVM&#xff08;Support Vector Machine&#xff09;、决策树&#xff08;Decision Tree&#xff09;和随机森林&#xff08;Random Forest&#xff09;是常见且广泛应用的算法。 介绍 1. KNN&am…

1-内核开发环境ubuntu+virtualbox+mobaXterm搭建

内核开发环境 ubuntuvirtualboxmobaXterm搭建 目录 内核开发环境 ubuntuvirtualboxmobaXterm搭建 1.virtualbox 安装 2.ubuntu 安装 3.网络设置 4.虚拟机安装ssh 服务&#xff0c;更新ubuntu 源安装基本软件 5.mobaXterm 个人免费版本安装 6.总结 本课程教程从0-1开始教…

ASP.NET某企业信息管理系统的设计与实现

摘 要 信息管理系统就是我们常说的MIS(Management Information System),它是一个计算机软硬件资源以及数据库的人-机系统。经过对题目和内容的分析,选用了Microsoft公司的ASP.NET开发工具,由于它提供了用于从数据库中访问数据的强大工具集,使用它可以建立开发比较完善的数据库…