题解

通常直接思考最佳策略是十分困难的,我们不妨思考每一种情况需要如何处理:

  1. 整个字符串只有一种字符

    若字符串长度为 \(1\),那么字符串本身即为答案;

    若字符串长度大于等于 \(2\),那么不存在可行方案

  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\) 的情况

    从只有两种字符的情况,易得到启发:出现次数最多的字符,每两个之间必须插入至少一个不同的字符

  3. 整个字符串有 \(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 重构字符串的更多相关文章

  1. [Swift]LeetCode767. 重构字符串 | Reorganize String

    Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...

  2. Java实现 LeetCode 767 重构字符串(ASCII的转换)

    767. 重构字符串 给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同. 若可行,输出任意可行的结果.若不可行,返回空字符串. 示例 1: 输入: S = "aab&qu ...

  3. python基础知识2——基本的数据类型——整型,长整型,浮点型,字符串

    磨人的小妖精们啊!终于可以归置下自己的大脑啦,在这里我要把--整型,长整型,浮点型,字符串,列表,元组,字典,集合,这几个知识点特别多的东西,统一的捯饬捯饬,不然一直脑袋里面乱乱的. 对于Python ...

  4. Java把长整型时间转成字符串日期

    数据库里存放的是timestamp格式,前端取得后是这种:1436255550710长整型时间截转换成"2015-07-07"这种格式呢? import java.io.IOExc ...

  5. Python基础:1.数据类型(空、布尔类型、整型、长整型、浮点型、字符串)

    提示:python版本2.7,windows系统 Python提供的基本数据类型:空.布尔类型.整型.长整型.浮点型.字符串.列表.元组.字典.日期 1.空(None) None,是一个特殊的值,不能 ...

  6. python基础一整型、bool、字符串

    1整型.bool.字符串 1.整型 --数字(int) ​ 用于比较运算的 ​ 32位 -2 ** 31 ~ 2 ** 31 -1 ​ 64位 -2 ** 63 ~ 2 ** 63 -1 ​ 基础运算 ...

  7. [Usaco 2012 Feb]Cow coupons牛券:反悔型贪心

    Description Farmer  John  needs  new  cows! There  are  N  cows  for  sale (1 <= N <= 50,000), ...

  8. [LeetCode] Reorganize String 重构字符串

    Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...

  9. [LeetCode] 767. Reorganize String 重构字符串

    Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...

  10. 整型(int)转时间格式字符串及页面long型转时间格式字符串

    1,如果是封装的整型的话需要在后台进行处理再返回页面 处理过程是这样的 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm ...

随机推荐

  1. maven安装本地jar命令

    mvn install:install-file -Dfile=jar包的位置 -DgroupId=pom.xml的groupId -DartifactId=pom.xm的artifactId -Dv ...

  2. python08_05day

    #!/usr/bin/python# -*- coding: UTF-8 -*-from _ast import Param #查询数据库'''import MySQLdb conn = MySQLd ...

  3. Idea启动多服务时的Dashboard展示

    1.提换.idea/workspace.xml文件中的RunDashboard标签 <component name="RunDashboard"> <option ...

  4. 这些HTTP协议状态码你知道吗?

    使用ASP.NET/PHP/JSP 或者javascript都会用到http的不同状态,一些常见的状态码为: 200 – 服务器成功返回网页 404 – 请求的网页不存在 503 – 服务不可用 1x ...

  5. DOS特殊字符的转义方法

  6. Go下载依赖包失败的解决方法

    jenkins构建job,执行go test命令报如下图的timeout错误 从报错信息中可以看出是因为下载依赖包超时 解决方法: go env查看go环境变量 GOSUMDB=sum.golang. ...

  7. Clickhouse入门及实践

    ClickHouse安装 采用doker安装测试: 拉取服务端 docker pull yandex/clickhouse-server 拉取客户端 docker pull yandex/clickh ...

  8. Mac终端zsh设置快捷键的两种方法

    vim ~/.zshrc # 第一种 alias test_1='command' # 第二种 function test_2() { command }

  9. Cargo deny安装指路

    本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0许可协议.转载请注明来自 唯你 简介 cargo deny 是一个 Rust 工具,用于检查项目依赖项的许可证.安全性和其他合规性问题. ...

  10. k8s之容器运行时

    Kubernetes 中的容器运行时 容器运行时(Container Runtime)是 Kubernetes 最重要的组件之一,负责真正管理镜像和容器的生命周期.Kubelet 通过 Contain ...