【相邻不同型贪心】LeetCode767 重构字符串
题解
通常直接思考最佳策略是十分困难的,我们不妨思考每一种情况需要如何处理:
整个字符串只有一种字符
若字符串长度为 \(1\),那么字符串本身即为答案;
若字符串长度大于等于 \(2\),那么不存在可行方案整个字符串只有两种字符 \(c_1,c_2\),数量分别为 \(n_1,n_2\)
若字符 \(c_1\) 的数量 \(n_1\) == 字符 \(c_2\) 的数量 \(n_2\),明显字符 \(c_1\) 和字符 \(c_2\) 交替出现即可
若字符 \(c_1\) 的数量 \(n_1\) > 字符 \(c_2\) 的数量 \(n_2\),那么每两个字符 \(c_1\) 之间必须插入一个字符 \(c_2\),也就是 \(n_1 - 1 \leq n_2\)。进一步思考,\(abs(n_1-n_2)\) 可以大于 \(1\) 吗?答案是不行,因为无法为每两个字符 \(c_1\) 之间插入一个字符 \(c_2\)
若字符 \(c_1\) 的数量 \(n_1\) < 字符 \(c_2\) 的数量 \(n_2\),情况类似于 \(n_1 > n_2\) 的情况
从只有两种字符的情况,易得到启发:出现次数最多的字符,每两个之间必须插入至少一个不同的字符整个字符串有 \(n(1 \leq n \leq 26)\) 种字符,第 \(i\) 种字符的数量为 \(n_i\)
由只有两种字符的字符串重构成功的方案来看,在有 \(n\) 种类字符的字符串中,需要首先处理出现次数最多的元素,不妨记出现次数为 \(m = max(n_i)\)
如下图所示,至少需要在 \(m\) 个元素之间插入一个与左右相邻元素均不同的元素:
所以,只需要将 \(m\) 个出现次数最多的元素(若有多个出现次数最多的元素,任意选择其中一个即可)先依次放入位置 \(x_j(1 \leq j \leq m)\),随后将剩下的全部元素,按种类依次从位置 \(x_1\) 填到为止 \(x_m\)即可。
若 全部元素个数 - \(m < m - 1\),则无解,否则有解。
问:为什么维护出现次数最多的种类元素是可行的方案?
答:因为题目要求的是相邻两个元素不可相同,那么在字符串中全部种类的单种元素的出现次数都不会超过\(max(n_i)\)。因此,只需要先维护其中一个出现次数最多的元素,并将剩余的元素按种类依次填入这\(max(n_i)\)个元素之后,必定符合每两个相邻元素不同的要求。按种类填入指的是,按单种元素依次从前往后连续插入(换一种元素后从上次插入的位置之后的第一个位置开始)。
参考代码
class Solution {
public:
string reorganizeString(string s) {
string ans;
vector<int> mp(26);
for (auto &it: s) {
mp[it - 'a'] ++;
}
int mx = 0, idx = 0, sum = 0;
for (int i = 0; i < 26; ++ i) {
if (mx < mp[i]) {
mx = mp[i];
idx = i;
}
sum += mp[i];
}
if (sum - mx >= mx - 1) {
vector<vector<char>> v(mx);
for (auto &it: v) {
it.push_back('a' + idx);
}
mp[idx] = 0;
int cur = 0;
for (int i = 0; i < 26; ++ i) {
while (mp[i] > 0) {
v[cur].emplace_back('a' + i);
cur = (cur + 1) % mx;
-- mp[i];
}
}
for (auto &u: v) {
for (auto &i: u) {
ans.push_back(i);
}
}
}
return ans;
}
};
【相邻不同型贪心】LeetCode767 重构字符串的更多相关文章
- [Swift]LeetCode767. 重构字符串 | Reorganize String
Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...
- Java实现 LeetCode 767 重构字符串(ASCII的转换)
767. 重构字符串 给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同. 若可行,输出任意可行的结果.若不可行,返回空字符串. 示例 1: 输入: S = "aab&qu ...
- python基础知识2——基本的数据类型——整型,长整型,浮点型,字符串
磨人的小妖精们啊!终于可以归置下自己的大脑啦,在这里我要把--整型,长整型,浮点型,字符串,列表,元组,字典,集合,这几个知识点特别多的东西,统一的捯饬捯饬,不然一直脑袋里面乱乱的. 对于Python ...
- Java把长整型时间转成字符串日期
数据库里存放的是timestamp格式,前端取得后是这种:1436255550710长整型时间截转换成"2015-07-07"这种格式呢? import java.io.IOExc ...
- Python基础:1.数据类型(空、布尔类型、整型、长整型、浮点型、字符串)
提示:python版本2.7,windows系统 Python提供的基本数据类型:空.布尔类型.整型.长整型.浮点型.字符串.列表.元组.字典.日期 1.空(None) None,是一个特殊的值,不能 ...
- python基础一整型、bool、字符串
1整型.bool.字符串 1.整型 --数字(int) 用于比较运算的 32位 -2 ** 31 ~ 2 ** 31 -1 64位 -2 ** 63 ~ 2 ** 63 -1 基础运算 ...
- [Usaco 2012 Feb]Cow coupons牛券:反悔型贪心
Description Farmer John needs new cows! There are N cows for sale (1 <= N <= 50,000), ...
- [LeetCode] Reorganize String 重构字符串
Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...
- [LeetCode] 767. Reorganize String 重构字符串
Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...
- 整型(int)转时间格式字符串及页面long型转时间格式字符串
1,如果是封装的整型的话需要在后台进行处理再返回页面 处理过程是这样的 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm ...
随机推荐
- 系统编程-进程-exec系列函数超级详解(带各种实操代码)
我的相关博文: 系统编程-进程-close-on-exec机制 PART1 exec系列函数功能简介 exec系列函数登场 常规操作是先fork一个子进程,然后在子进程中调用exec系列函数执行新的 ...
- 系统 内核启动期间使用ftrace
启动阶段使能event trace 同上,配置commandline: trace_event=sched:*,timer:*,irq:* trace_buf_size=40M 有上面的实例可以知道, ...
- kdump
Kdump简单介绍 什么是Kdump? Kdump是在系统崩溃.死锁或死机时用来转储内存运行参数的一个工具和服务,是一种新的crash dump捕获机制,用来捕获kernel crash(内核崩溃)的 ...
- Java日期时间API系列27-----Jdk8中java.time包中的新的日期时间API类,使用xk-time工具类创建日历应用,自定义节假日,工作日和打印日历表。
1.日历相关类 1.1 日历类 CalendarWrapper package com.xkzhangsan.time.calendar; import java.io.Serializable; i ...
- ADO.NET 事务 transaction
事务回滚:
- LEAP: Learning to Prescribe Effective and Safe Treatment Combinations for Multimorbidity
LEAP: Learning to Prescribe Effective and Safe Treatment Combinations for Multimorbidity Authors: Yu ...
- 云原生周刊 | 在 Grafana 中显示 K8s Service 之间的依赖关系
开源项目推荐 Caretta 这个项目可以在 Grafana 监控面板中显示 K8s Service 之间的依赖关系.底层使用的是 eBPF,对应用无侵入. busuanzi 这是一个基于 Golan ...
- vi指令总结
VI常用技巧 VI命令可以说是Unix/Linux世界里最常用的编辑文件的命令了,但是因为它的命令集众多,很多人都不习惯使用它,其实您只需要掌握基本命令,然后加以灵活运用,就会发现它的优势,并会逐 ...
- 2024CSP-J游记
拿到题的第一步,先看第一题,大致扫了一眼,水题.以为是hash,进一步思考了一下,hash不行.发现可以用set,于是拿set敲了一下,样例全对. 第二题,看了眼样例以为是DFS.实际看了看发现是模拟 ...
- 使用NodeJS 搭建 Vue + TypeScipt 快速构建工具
使用 NodeJS 搭建 Vue + TypeScipt 快速构建工具 前言: 为保证使用 Typescript 开发 Vue 的规范性和开发效率,添加组件.页面.路由.store 的时候尽量使用工具 ...