算法学习——LeetCode力扣贪心篇4

算法学习——LeetCode力扣贪心篇4

在这里插入图片描述

763. 划分字母区间

763. 划分字母区间 - 力扣(LeetCode)

描述

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。

返回一个表示每个字符串片段的长度的列表。

示例

示例 1:
输入:s = “ababcbacadefegdehijhklij”
输出:[9,7,8]
解释:
划分结果为 “ababcbaca”、“defegde”、“hijhklij” 。
每个字母最多出现在一个片段中。
像 “ababcbacadefegde”, “hijhklij” 这样的划分是错误的,因为划分的片段数较少。

示例 2:

输入:s = “eccbbbbdec”
输出:[10]

提示

  • 1 <= s.length <= 500
  • s 仅由小写英文字母组成
代码解析

题意简述为
即最多能切多少段?使得同一字母都出现在一个片段,且片段最多。

思路
先统计整个字符串的map字典。
然后再次遍历字符串,当遍历字符串某一点时,当前字符串区间出现的字母个数就是整个字符串的字母个数(即当前字符串区间出现的字母,全部都出现在这里,区间外没有这个字母再次出现了),纪录当前区间是一段。

class Solution {
public:vector<int> partitionLabels(string s) {map<char,int> my_map; //整个字符串字典map<char,int> my_map_tmp;// 一段的字典vector<int> result;int start = 0; //段开始标志for(int i=0 ; i< s.size() ; i++) my_map[s[i]]++;// for(auto it:my_map) cout<<it.first<<' '<<it.second<<endl;for(int i=0 ; i<s.size() ;i++){my_map_tmp[s[i]]++; //更新一段的字典//检查当前的字典和全局字典,字母出现的次数for(auto it = my_map_tmp.begin() ; it != my_map_tmp.end() ;it++){//当前段中字母出现个数和全局不同(即还有字母没发现),跳出if( it->second != my_map[it->first]) break;//当前段出现的字母,字母数量和全局数量都相同(即全发现)if(it == -- my_map_tmp.end() ) //遍历到最后一个字母都没跳出{result.push_back(i-start+1); //记录段长度start = i+1; //下一段开始点my_map_tmp.clear();//清空段字典}}}return result;}
};

56. 合并区间

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

描述

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

代码解析

按照左边界排序,排序之后局部最优:每次合并都取最大的右边界,这样就可以合并更多的区间了,整体最优:合并所有重叠的区间。

其实就是用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。

class Solution {
public:static bool compare(vector<int>&a , vector<int>&b){return a[0] < b[0];}vector<vector<int>> merge(vector<vector<int>>& intervals) {if(intervals.size() <= 1) return intervals;vector<vector<int>> result;//按照区间左边界排序sort(intervals.begin() , intervals.end(),compare);//第一个区间作为临时区间vector<int> tmp = intervals[0];for(int i = 1 ; i< intervals.size() ; i++){//如果当前区间和临时区间有重叠//取临时区间和当前区间的公共集合作为新的临时区间if(tmp[1] >= intervals[i][0]){tmp[0] = min(tmp[0] , intervals[i][0]);tmp[1] = max(tmp[1] , intervals[i][1]);}else//当临时区间和当前区间不重合{result.push_back(tmp);//临时区间存入tmp = intervals[i];//当前区间为新的临时区间}if(i==intervals.size()-1)//当前区间是最后一个区间的时候{result.push_back(tmp);//存入未存入的临时区间}}return result;}
};

738. 单调递增的数字

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

描述

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

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

示例

示例 1:

输入: n = 10
输出: 9

示例 2:

输入: n = 1234
输出: 1234

示例 3:

输入: n = 332
输出: 299

提示

  • 0 <= n <= 109

代码解析

找到一个比目标值小的最大递增数列

递归法

从左到右遍历,找符合递增的部分,
当发现不符合的部分,不符合部分都置9
找到符合部分-1的最大递增数(后面都置9要借位)

例:输入668841
发现6688部分符合递增,但是从4开始不符合,因此41变成99
之后找到6688-1的最大递增(后面99要借1)为6679
在和最后两个99合并,得到667999

class Solution {
public:int monotoneIncreasingDigits(int n) {if(n<10) return n;string num = to_string(n);string result ;result += num[0];int flag = 0; //是否符合标志位,当不符合递增的时候,后面都置9for(int i=1 ;i<num.size();i++) //遍历{if(num[i] >= num[i-1] && flag==0) //找到符合递增的部分{result += num[i];}else if(flag==0) //找到第一个不符合递增的数 ,并求之前符合部分-1最大递增{result = to_string(monotoneIncreasingDigits(stoi(result)-1) );flag = 1; //设置为不符合}if(flag == 1) //不符合后面全都置9{result += '9';}}return stoi(result);}
};
贪心法 反向遍历

局部最优:遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]–,然后strNum[i]给为9,可以保证这两位变成最大单调递增整数。

全局最优:得到小于等于N的最大单调递增的整数。

但这里局部最优推出全局最优,还需要其他条件,即遍历顺序,和标记从哪一位开始统一改成9。

那么从后向前遍历,就可以重复利用上次比较得出的结果了,从后向前遍历332的数值变化为:332 -> 329 -> 299

class Solution {
public:int monotoneIncreasingDigits(int n) {if(n<10) return n;string num = to_string(n);int flag;for(int i=num.size()-1 ; i >=1 ;i--){if(num[i] < num[i-1]){flag = i;num[i-1] -= 1;}}for(int i = flag ; i<num.size() ;i++){num[i] = '9';}return stoi(num);}
};

968. 监控二叉树

968. 监控二叉树 - 力扣(LeetCode)

描述

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

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

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

示例

示例 1:

在这里插入图片描述

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

示例 2:

在这里插入图片描述

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

提示

  • 给定树的节点数的范围是 [1, 1000]。
  • 每个节点的值都是 0。

代码解析

从下往上看,局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!
此时,大体思路就是从低到上,先给叶子节点父节点放个摄像头,然后隔两个节点放一个摄像头,直至到二叉树头结点。

我们分别有三个数字来表示:

0:该节点无覆盖
1:本节点有摄像头
2:本节点有覆盖

  • 情况1:左右节点都有覆盖
    左孩子有覆盖,右孩子有覆盖,那么此时中间节点应该就是无覆盖的状态了。
    在这里插入图片描述

  • 情况2:左右节点至少有一个无覆盖的情况
    如果是以下情况,则中间节点(父节点)应该放摄像头:

在这里插入图片描述

  • 情况3:左右节点至少有一个有摄像头
    如果是以下情况,其实就是 左右孩子节点有一个有摄像头了,那么其父节点就应该是2(覆盖的状态)
  • 情况4:头结点没有覆盖
    以上都处理完了,递归结束之后,可能头结点 还有一个无覆盖的情况,如图:

在这里插入图片描述

class Solution {
private:int result;int traversal(TreeNode* cur) {// 空节点,该节点有覆盖if (cur == NULL) return 2;int left = traversal(cur->left);    // 左int right = traversal(cur->right);  // 右// 情况1// 左右节点都有覆盖if (left == 2 && right == 2) return 0;// 情况2// left == 0 && right == 0 左右节点无覆盖// left == 1 && right == 0 左节点有摄像头,右节点无覆盖// left == 0 && right == 1 左节点有无覆盖,右节点摄像头// left == 0 && right == 2 左节点无覆盖,右节点覆盖// left == 2 && right == 0 左节点覆盖,右节点无覆盖if (left == 0 || right == 0) {result++;return 1;}// 情况3// left == 1 && right == 2 左节点有摄像头,右节点有覆盖// left == 2 && right == 1 左节点有覆盖,右节点有摄像头// left == 1 && right == 1 左右节点都有摄像头// 其他情况前段代码均已覆盖if (left == 1 || right == 1) return 2;// 以上代码我没有使用else,主要是为了把各个分支条件展现出来,这样代码有助于读者理解// 这个 return -1 逻辑不会走到这里。return -1;}public:int minCameraCover(TreeNode* root) {result = 0;// 情况4if (traversal(root) == 0) { // root 无覆盖result++;}return result;}
};

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

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

相关文章

【C++】---类和对象(中)默认成员函数 和 操作符重载

前言&#xff1a; 假如一个类中既没有成员变量也没有成员函数&#xff0c;那么这个类就是空类&#xff0c;空类并不是什么都没有&#xff0c;因为所有类都会生成如下6个默认成员函数&#xff1a; 一、构造函数 1、构造函数的定义及其特性 对于日期类对象&#xff0c;我们可…

基于matlab的密度散点图绘制

1. 什么是密度散点图&#xff1f; 密度散点图就是在普通散点图的基础上&#xff0c;基于样本点一定范围的样本数计算该样本点的密度&#xff0c;以不同的颜色来显示样本点密度的大小&#xff0c;这样能够直观的显示出数据的空间聚集情况&#xff0c;如下图分别是二维和三维密度…

【教程】C++语言基础学习笔记(六)——String字符串

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【C语言基础学习】系列文章 第一章 《项目与程序结构》 第二章 《数据类型》 第三章 《运算符》 第四章 《流程控制》 第五章…

[word] word保存了但是再打开就没有了怎么办 #职场发展#其他

word保存了但是再打开就没有了怎么办 word保存了但是再打开就没有了怎么办&#xff1f; 一些朋友反映常常找不到自己保存在电脑中的Word的文档&#xff0c;不知道是怎么回事。如果是突然消失的&#xff0c;其实情况还是有很多种&#xff0c;相信大家也有一定的了解。在这里&a…

阿里云幻兽帕鲁Linux 服务器下载游戏存档的方法

阿里云幻兽帕鲁Linux 服务器下载游戏存档的方法也非常简单。 远程连接到阿里云的 linux服务器后&#xff0c;可以在 ECS 远程连接命令行界面&#xff0c;点击左上角的文件&#xff0c;打开文件树。通过一行命令打包。 在打包后的 Saved.tar 文件上右键&#xff0c;选择 下载文…

【python】python入门(输出)

本篇文章将会介绍关于python的常见输出&#xff0c;希望对您有帮助&#xff01; 输出 用到print函数 print(oh mygod)##或者 print("oh mygod")##或者 print("oh"" ""mygod") 输出结果&#xff1a; 用单引号、双引号都可以 ,引号中可…

下一代Windows系统曝光:基于GPT-4V,Agent跨应用调度,代号UFO

下一代Windows操作系统提前曝光了&#xff1f;&#xff1f; 微软首个为Windows而设的智能体&#xff08;Agent&#xff09; 亮相&#xff1a; 基于GPT-4V&#xff0c;一句话就可以在多个应用中无缝切换&#xff0c;完成复杂任务。整个过程无需人为干预&#xff0c;其执行成功…

【Qt】qt常用控件之QIcon 以及 qrc机制设置图片路径(QtCreator)

文章目录 1. QIcon / windowIcon2. setIcon() 与 setwindowIcon()2.1 setIcon() 介绍与使用2.2 setWindowIcon 介绍与使用 3. 路径问题 & qrc机制的引入3.1 绝对路径 / 相对路径 的问题3.2 qrc机制3.3 在QtCreator下利用qrc机制引入图片 1. QIcon / windowIcon QIcon QIco…

PR:时间重映射

做一个变换视频速度的效果 原片如下&#xff1a; 现在将跑步的人中间一段加速&#xff0c;后面一段减速 操作如下&#xff1a; 此处点击关键帧时&#xff0c;可以用钢笔工具&#xff0c;也可以按住Ctrl键点击 操作后效果如下&#xff1a;

Write operation failed: computed value is readonly问题解决

源代码&#xff1a; // 封装倒计时逻辑函数 import { computed, ref } from vue import dayjs from dayjs export const useCountDown () > {// 1.响应式数据const time ref(0)// 格式化时间const formatTime computed(()>dayjs.unix(time.value).format(mm分ss秒))/…

最短路径与关键路径

目录 文章目录 前言 一.最短路径 1.基本概念 1.1什么是源点&#xff1f; 1.2什么是最短路径 2.作用 3.迪杰斯特拉算法 4. 弗洛伊德算法 4.1过程演示 二.拓扑排序 1.基本概念 1.1什么是有向无环图 1.2什么是活动 1.3什么是AOV网 1.4什么是拓扑序列 1.5什么是拓扑…

Ubuntu 23.10通过APT安装Open vSwitch

正文共&#xff1a;888 字 8 图&#xff0c;预估阅读时间&#xff1a;1 分钟 先拜年&#xff01;祝各位龙年行大运&#xff0c;腾跃展宏图&#xff01; 之前在介绍OpenStack的时候介绍过&#xff08;什么是OpenStack&#xff1f;&#xff09;&#xff0c;OpenStack是一个开源的…

Python slice函数

在Python编程中&#xff0c;slice&#xff08;切片&#xff09;操作是一种强大且灵活的方式&#xff0c;用于从序列&#xff08;如列表、元组、字符串等&#xff09;中获取子序列。通过切片操作&#xff0c;可以轻松地提取序列中的一部分&#xff0c;进行遍历、修改、复制等操作…

指针习题回顾(C语言)

目录 数组指针和指针数组 编程题&#xff1a; 字符串逆序 字符串左旋 题目1概述&#xff1a; 代码实现&#xff1a; 题目2概述&#xff1a; 代码实现&#xff1a; 调整奇偶顺序 题目概述&#xff1a; 代码实现&#xff1a; 冒泡排序 二级指针 代码解读&#xff1a; …

【AIGC】Stable Diffusion的插件入门

一、上文中作者使用插件包的方式下安装插件&#xff0c;用户也可以从Stable Diffusion的界面安装插件&#xff0c;如下图所示&#xff0c;在相应的插件后面点安装按钮。 二、介绍一些比较好用的插件 “adetailer” 插件是 Stable Diffusion 中的一个增强功能&#xff0c;旨在提…

【Pygame手册02/20】pygame模块display控制窗口和屏幕

目录 一、说明二、pygame.display接口函数2.1 函数表格2.2 pygame.display的功能 三、详细的函数调用3.1 pygame.display.init()3.2 pygame.display.quit()3.3 pygame.display.get_init()3.4 pygame.display.set_mode()3.5 pygame.display.get_surface()3.6 pygame.display.fl…

飞天使-k8s知识点18-kubernetes实操3-pod的生命周期

文章目录 探针的生命周期流程图prestop 探针的生命周期 docker 创建&#xff1a;在创建阶段&#xff0c;你需要选择一个镜像来运行你的应用。这个镜像可以是公开的&#xff0c;如 Docker Hub 上的镜像&#xff0c;也可以是你自己创建的自定义镜像。创建自己的镜像通常需要编写一…

【AIGC】Stable Diffusion的采样器入门

在 Stable Diffusion 中&#xff0c;采样器&#xff08;Sampler&#xff09;是指用于生成图像的一种技术或方法&#xff0c;它决定了模型如何从潜在空间中抽样并生成图像。采样器在生成图像的过程中起着重要作用&#xff0c;影响着生成图像的多样性、质量和创造性。以下是对 St…

为自监督学习重构去噪扩散模型

在这项研究中&#xff0c;作者检验了最初用于图像生成的去噪扩散模型&#xff08;DDM&#xff09;的表示学习能力。其理念是解构DDM&#xff0c;逐渐将其转化为经典的去噪自动编码器&#xff08;DAE&#xff09;。这一解构过程让大家能够探索现代DDM的各个组成部分如何影响自监…

python自学...

一、稍微高级一点的。。。 1. 闭包&#xff08;跟js差不多&#xff09; 2. 装饰器 就是spring的aop 3. 多线程