1.题目描述
给你一个字符串 text ,该字符串由若干被空格包围的单词组成。每个单词由一个或者多个小写英文字母组成,并且两个单词之间至少存在一个空格。题目测试用例保证 text 至少包含一个单词 。
请你重新排列空格,使每对相邻单词之间的空格数目都 相等 ,并尽可能 最大化 该数目。如果不能重新平均分配所有空格,请 将多余的空格放置在字符串末尾 ,这也意味着返回的字符串应当与原 text 字符串的长度相等。
返回 重新排列空格后的字符串 。
示例 1:
输入:text = " this is a sentence "
输出:"this is a sentence"
解释:总共有 9 个空格和 4 个单词。可以将 9 个空格平均分配到相邻单词之间,相邻单词间空格数为:9 / (4-1) = 3 个。
示例 2:
输入:text = " practice makes perfect"
输出:"practice makes perfect "
解释:总共有 7 个空格和 3 个单词。7 / (3-1) = 3 个空格加上 1 个多余的空格。多余的空格需要放在字符串的末尾。
示例 3:
输入:text = "hello world"
输出:"hello world"
示例 4:
输入:text = " walks udp package into bar a"
输出:"walks udp package into bar a "
示例 5:
输入:text = "a"
输出:"a"
2.解题思路与代码
2.1 解题思路
非常简单的一道字符串应用题,首先我们需要统计出给定字符串 text 中的单词个数和空格个数,遍历一次字符串进行统计,统计时遇到空格则空格个数加一,使用一个 StringBuilder 对象存放遇到的字符,每遇到一个字符放入 StringBuilder 对象中,如果遇到一个空格并且此时 StringBuilder 对象的长度不为 0 ,说明此时已经遍历完一个单词,将 StringBuilder 对象转换成字符串存入列表中,注意遍历完 text 之后需要看看此时的 StringBuilder 对象是否还有内容,如果长度不为零 需要将剩余内容放入单词列表中。代码如下:
int spaceCount = 0;
List<String> list = new ArrayList<>();
StringBuilder tmp = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == ' ') {
// 遇到空格计数加一
spaceCount++;
// 判断此时的 StringBuilder 对象长度是否为 0, 不为 0 表示一个单词遍历完成
if (tmp.length() != 0) {
list.add(tmp.toString());
tmp = new StringBuilder();
}
} else {
tmp.append(text.charAt(i));
}
}
// 遍历完 text 之后StringBuilder 长度不为 0 将内容放入单词列表中
if (tmp.length() > 0) {
list.add(tmp.toString());
}
通过上面的代码我们便统计到了这个字符串中的单词列表和空格个数,接下来就是对单词重组空格了。首先我们需要计算出两个单词间平均分配的空格个数,就是用总的空格个数除以单词个数减一的差,如果此时单词个数是 1 的话则不需要分配空格。然后还需要计算分配后剩余的空格个数,用总的空格数减去已分配的空格数就可以了,代码如下:
// 单词个数
int wordCount = list.size();
// 两个单词间分配的空格数
int wordSpace = wordCount == 1 ? 0 : spaceCount / (wordCount - 1);
// 剩余放入结尾的空格数
int lastSpace = wordCount == 1 ? spaceCount : spaceCount % (wordCount - 1);
最后便是重组 text 的过程了,遍历单词列表,每遇到一个单词就在后面追加相应个数 wordSpace 的空格,最后再在结尾追加 lastSpace 个空格,返回字符串即可。
2.2 代码
class Solution {
public String reorderSpaces(String text) {
int spaceCount = 0;
List<String> list = new ArrayList<>();
StringBuilder tmp = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == ' ') {
spaceCount++;
if (tmp.length() != 0) {
list.add(tmp.toString());
tmp = new StringBuilder();
}
} else {
tmp.append(text.charAt(i));
}
}
if (tmp.length() > 0) {
list.add(tmp.toString());
}
if (spaceCount == 0) {
return text;
}
int wordCount = list.size();
int wordSpace = wordCount == 1 ? 0 : spaceCount / (wordCount - 1);
int lastSpace = spaceCount - wordSpace * (wordCount - 1);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
builder.append(list.get(i));
if (i != list.size() - 1) {
for (int j = 0; j < wordSpace; j++) {
builder.append(" ");
}
}
}
for (int i = 0; i < lastSpace; i++) {
builder.append(" ");
}
return builder.toString();
}
}
2.3 测试结果
通过测试
3.总结
- 先遍历字符串统计处字符串中的单词列表和总空格数
- 计算两个单词间的空格数以及多余放在结尾的空格数,根据这两个空格数重组字符串即可