LeetCode 每日一题——1592. 重新排列单词间的空格

这是一篇关于字符串处理的博客,主要介绍了如何重新排列字符串中的空格,使得相邻单词间的空格数量相等。文章通过示例解释了算法思路,包括统计单词和空格、计算平均空格数、重组字符串等步骤,并提供了相应的Java代码实现。
摘要由CSDN通过智能技术生成

1.题目描述

1592. 重新排列单词间的空格

给你一个字符串 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.总结

  • 先遍历字符串统计处字符串中的单词列表和总空格数
  • 计算两个单词间的空格数以及多余放在结尾的空格数,根据这两个空格数重组字符串即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值