Day9 字符串

10

反转字符串中的单词

class Solution {
    /**
     * 反转字符串中的单词顺序
     * 步骤:
     * 1. 去除首尾及中间多余空格
     * 2. 反转整个字符串
     * 3. 反转每个单词
     */
    public String reverseWords(String s) {
        // 1. 去除多余空格
        StringBuilder sb = removeExtraSpaces(s);
        // 2. 反转整个字符串
        reverseString(sb, 0, sb.length() - 1);
        // 3. 反转每个单词
        reverseEachWord(sb);
        return sb.toString();
    }

    /**
     * 去除首尾及中间多余空格
     * 优化点:
     * - 使用双指针直接在原字符串上遍历,避免多次条件判断
     * - 更简洁的空格处理逻辑
     */
    private StringBuilder removeExtraSpaces(String s) {
        int left = 0;
        int right = s.length() - 1;
        // 去除首尾空格
        while (left <= right && s.charAt(left) == ' ') left++;
        while (left <= right && s.charAt(right) == ' ') right--;

        StringBuilder sb = new StringBuilder();
        while (left <= right) {
            char c = s.charAt(left);
            // 如果当前字符不是空格,直接添加
            if (c != ' ') {
                sb.append(c);
            }
            // 如果当前字符是空格,且前一个字符不是空格(避免连续空格),则添加
            else if (sb.charAt(sb.length() - 1) != ' ') {
                sb.append(c);
            }
            left++;
        }
        return sb;
    }

    /**
     * 反转字符串指定区间 [start, end] 的字符
     */
    private void reverseString(StringBuilder sb, int start, int end) {
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }
    }

    /**
     * 反转每个单词
     * 优化点:
     - 直接遍历 StringBuilder,避免额外索引计算
     - 更清晰的单词边界处理
     */
    private void reverseEachWord(StringBuilder sb) {
        int start = 0;
        int end = 0;
        int n = sb.length();
        while (start < n) {
            // 找到单词的起始位置
            while (start < n && sb.charAt(start) == ' ') start++;
            // 找到单词的结束位置
            end = start;
            while (end < n && sb.charAt(end) != ' ') end++;
            // 反转单词,end 停下的位置是单词的下一个字符
            reverseString(sb, start, end - 1);
            // 移动到下一个单词
            start = end;
        }
    }
}