【贪心 堆 】3081. 替换字符串中的问号使分数最小

2024-04-17 18:44

本文主要是介绍【贪心 堆 】3081. 替换字符串中的问号使分数最小,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算法可以发掘本质,如:
一,若干师傅和徒弟互有好感,有好感的师徒可以结对学习。师傅和徒弟都只能参加一个对子。如何让对子最多。
二,有无限多1X2和2X1的骨牌,某个棋盘若干格子坏了,如何在没有坏的格子放足够多骨牌。
三,某个单色图,1表示前前景,0表示后景色。每次操作可以将一个1,变成0。如何在最少得操作情况下,使得没有两个1相邻(四连通)。
四,若干路人,有些人是熟人,如何选出最多的人参加实验。为了避免熟人影响实验的效果,参加的人不能是熟人。
一二是二分图的最大匹配,三是二分图的最小点覆盖,四是二分图最大独立集。 而这三者是等效问题。

本文涉及知识点

贪心 堆

LeetCode 3081. 替换字符串中的问号使分数最小

给你一个字符串 s 。s[i] 要么是小写英文字母,要么是问号 ‘?’ 。
对于长度为 m 且 只 含有小写英文字母的字符串 t ,我们定义函数 cost(i) 为下标 i 之前(也就是范围 [0, i - 1] 中)出现过与 t[i] 相同 字符出现的次数。
字符串 t 的 分数 为所有下标 i 的 cost(i) 之 和 。
比方说,字符串 t = “aab” :
cost(0) = 0
cost(1) = 1
cost(2) = 0
所以,字符串 “aab” 的分数为 0 + 1 + 0 = 1 。
你的任务是用小写英文字母 替换 s 中 所有 问号,使 s 的 分数最小 。
请你返回替换所有问号 ‘?’ 之后且分数最小的字符串。如果有多个字符串的 分数最小 ,那么返回字典序最小的一个。
示例 1:
输入:s = “???”
输出: “abc”
解释:这个例子中,我们将 s 中的问号 ‘?’ 替换得到 “abc” 。
对于字符串 “abc” ,cost(0) = 0 ,cost(1) = 0 和 cost(2) = 0 。
“abc” 的分数为 0 。
其他修改 s 得到分数 0 的字符串为 “cba” ,“abz” 和 “hey” 。
这些字符串中,我们返回字典序最小的。
示例 2:
输入: s = “a?a?”
输出: “abac”
解释:这个例子中,我们将 s 中的问号 ‘?’ 替换得到 “abac” 。
对于字符串 “abac” ,cost(0) = 0 ,cost(1) = 0 ,cost(2) = 1 和 cost(3) = 0 。
“abac” 的分数为 1 。
提示:
1 <= s.length <= 105
s[i] 要么是小写英文字母,要么是 ‘?’ 。

贪心

令各字母最多出现m次。
n个相同的字母,贡献的分数是: (n-1)+ (n-2) ⋯ \cdots + n + 1 = n *(n-1)/2 ,和n的平方有关。
显然每个?都替换当前最少的字符,如果相等则替换最小的字符。

性质一:替换出现次数少的是局部最优解

假定两个字母分别出现了a 次,b次。
方法一:?变a。
方法二:?变b。
方案一:(a+1)a/2 + b(b-1)/2
方案二:a*(a-1)/2 + (b+1)b/2
方案一
2 : a2+a + b2-b
方案二*2:a2-a + b2 +b
两者相减: 2(a-b)
{ 替换成 a ,分数更小。 a < b 都一样。 a = = b 替换成 b , 分数更小。 a > b \begin{cases} 替换成a,分数更小。 && a < b \\ 都一样。 && a == b \\ 替换成b,分数更小。 && a > b \\ \end{cases} 替换成a,分数更小。都一样。替换成b,分数更小。a<ba==ba>b

证明一:不能将所有字符全部换到m个

对于任意a < b。 假定在a <b时,b增加了若干次。则a++,b–直到 a == b,或次数用完。根据性质一,这样更优。

证明二:能全部换成m个

所有字符出现次数只会是x1和x1+1。如果有数c小于x,则不然有数d大于等于x+1。
c++,d–,会更优。

代码

核心代码

class Solution {
public:string minimizeStringValue(string s) {int cnt[26] = { 0 };int star = 0;for (const auto& ch : s) {if ('?' == ch) {star++;}else{cnt[ch - 'a']++;}}std::priority_queue<pair<int,int>, vector<pair<int, int>>, greater<>> minHeap;for (int i = 0; i < 26; i++) {minHeap.emplace(make_pair(cnt[i],i));}while (star > 0) {auto [cnt,i1] = minHeap.top();minHeap.pop();minHeap.emplace(make_pair(cnt + 1,i1));star--;}int cnt2[26] = { 0 };while (minHeap.size()) {auto [iCnt, i1] = minHeap.top();minHeap.pop();cnt2[i1] = iCnt - cnt[i1];}for (int i = 0, j = 0; i < s.length(); i++) {if ('?' != s[i]) { continue; }while (0 == cnt2[j]) {j++;}cnt2[j]--;s[i] = j + 'a';}return s;}
};

测试用例

int main()
{	string s;{Solution sln;s = "???";auto res = sln.minimizeStringValue(s);Assert(string("abc"), res);}{Solution sln;s = "a?a?";auto res = sln.minimizeStringValue(s);Assert(string("abac"), res);}}

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

这篇关于【贪心 堆 】3081. 替换字符串中的问号使分数最小的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

如何将Tomcat容器替换为Jetty容器

《如何将Tomcat容器替换为Jetty容器》:本文主要介绍如何将Tomcat容器替换为Jetty容器问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat容器替换为Jetty容器修改Maven依赖配置文件调整(可选)重新构建和运行总结Tomcat容器替

python中字符串拼接的几种方法及优缺点对比详解

《python中字符串拼接的几种方法及优缺点对比详解》在Python中,字符串拼接是常见的操作,Python提供了多种方法来拼接字符串,每种方法有其优缺点和适用场景,以下是几种常见的字符串拼接方法,需... 目录1. 使用 + 运算符示例:优缺点:2. 使用&nbsjsp;join() 方法示例:优缺点:3

java字符串数字补齐位数详解

《java字符串数字补齐位数详解》:本文主要介绍java字符串数字补齐位数,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java字符串数字补齐位数一、使用String.format()方法二、Apache Commons Lang库方法三、Java 11+的St

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示