刷刷刷Day8| 151. 反转字符串中的单词

151. 反转字符串中的单词

LeetCode题目要求

给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

示例

输入:s = "the sky is blue"
输出:"blue is sky the"
解题思路

按本题要求,是把字符串中的单词进行反转,其实是调换了单词的顺序,如果我们从反转单词的角度考虑,其实并不是太容易处理。
之前我们做过字符串的反转,再看这里其实可以先把整个字符串反转过来就是,从 “the sky is blue” 到 “eulb si yks eht”, 再观察,这是其实是每个单词的给自反转,只要再针对给每个单词做一次反转就得到了结果;
另外还有一个要求是,如果首尾或者中间有多余的空格都必须移除,每个单词中间只保留一个空格。
所以总体的解决思路是:1、反转整个字符串 2、反转各个单词(空格分割的子串) 3、去掉多余空格

上代码

class Solution {
    public String reverseWords(String s) {

        StringBuilder res = new StringBuilder();
         // 第一次整串反转 eulb si yks eht
        String r1 = reverse1(s);
        // 第二次反转前先获取到每一个单词,然后直接反转单词
        // tmp 用于存储每个单词
        StringBuilder tmp = new StringBuilder();
        for (int i = 0; i < r1.length(); i++) {
            // 遍历直接放入 tmp,不论是空格还是字母
            tmp.append(r1.charAt(i));
            // 当 tmp 中最后一个字符是空格(即完成一个单词的操作) 或者 遍历到最后一个单词(因为最后一个词结尾可能没有空格,所以这里的操作为了防止只判断空格会漏掉)
            if (tmp.charAt(tmp.length() - 1) == ' ' || i == r1.length() - 1) {
                // 反转各个单词成正确形式
                String rs = reverse1(tmp.toString());
                // 把正确的单词放入到 res 结果中,并且在结尾加一个空格,这里加空格主要为了操作方便,不然会出现各种问题,大家可以自己尝试一下
                res.append(rs).append(" ");
                // 清空 tmp, 便于下个单词使用
                tmp = new StringBuilder();
            }
        }

        int slow = 0;
        // 去掉多余的空格,
        // 快慢指针,快指针遍历,遇到非空的字符,就赋值给 slow 指针位置
        char[] cs = res.toString().toCharArray();
        //  上面使用了一次 res,这里因为要存结果,所以需要清空
        res = new StringBuilder();
        for (int fast = 0; fast < cs.length; fast++) {
            // fast 指针遍历,非空的就赋值存到 res 中
            if (cs[fast] != ' ') {
                // 这里指的是 slow 非第一个时,在中间单词之间加一个空格
                if (slow != 0) {
                    // cs[slow++] = ' ';
                    slow++;
                    res.append(' ');
                }
                // 单词的拼接,通过移动快指针,且值不为空得到一个单词,把每个字符都添加到res,且同时移动 slow,fast指针,这里如果不移动slow,就无法控制空格的位置了
                while (fast < cs.length && cs[fast] != ' ') {
                    // cs[slow++] = cs[fast++];
                    slow++;
                    res.append(cs[fast++]);
                }
            }
        }
        // 输出结果
        return res.toString();
    }
}
重难点

附:学习资料链接

posted @ 2023-01-09 16:02  blacksonny  阅读(22)  评论(0编辑  收藏  举报