151. 翻转字符串里的单词

128 阅读2分钟

思路 TC O(N), SC O(N)

步骤

  • 去除多余空格:
    • 两端
    • 中间连续两个空格
  • 翻转整个字符串
  • 逐个翻转单词

简洁

class Solution {
    public String reverseWords(String s) {
        String[] words = s.trim().split(" ");
        StringBuilder result = new StringBuilder();

        for (int i = words.length - 1; i >= 0; i--) {
            if (!words[i].isEmpty())
                result.append(words[i]).append(" ");
        }
        
        return result.toString().trim();
    }
}

好写法

  • 没有用到trim(), reverse(),只用了 sb.setCharAt().
class Solution {
    public String reverseWords(String s) {
        StringBuffer sb = new StringBuffer(s);
        sb = trimSpace(sb.toString()); //去除无效空格
        reverse(sb, 0, sb.length() - 1); // 整个翻转
        // 翻转内部单词
        int pre = 0;
        for (int i = 0; i <= sb.length(); i++) {
            if (i == sb.length() || sb.charAt(i) == ' ') { // 注意最后一个单词的翻转
                reverse(sb, pre, i - 1);
                pre = i + 1;
            }
        }
        return sb.toString();
    }

    // 翻转从start到end的字符串(包含strat end)
    public void reverse(StringBuffer sb, int start, int end) {
        int i = start, j = end;
        while (i < j) {
            char tmp = sb.charAt(i);
            sb.setCharAt(i, sb.charAt(j));
            sb.setCharAt(j, tmp);
            i++;
            j--;
        }
    }

    // 去除字符串两端空格 和 中间多余空格,返回一个新sb
    public StringBuffer trimSpace(String str) {
        StringBuffer sb = new StringBuffer();
        int m = 0, n = str.length() - 1;
        //两端遇到空格,直接跳过
        while (str.charAt(m) == ' ') {
            m++;
        }
        while (str.charAt(n) == ' ') {
            n--;
        }
        //去除中间的多余空格,追加到新sb上
        for (int i = m; i <= n; i++) {
            if (str.charAt(i) == ' ' && str.charAt(i + 1) == ' ') {
                continue;
            } else {
                sb.append(str.charAt(i));
            }
        }
        return sb;
    }
}

第一次写的垃圾写法

class Solution {
    public String reverseWords(String s) {
        StringBuffer sb = new StringBuffer(s.trim());//去除两端空格
        sb.reverse();
        //去除中间多余空格,开了一个新sb,把不含多余空格的string转移过去
        StringBuffer rev = new StringBuffer();
        for (int i = 0; i < sb.length(); i++) {
            if (sb.charAt(i) != ' ') {
                rev.append(sb.charAt(i));
            } else if (sb.charAt(i) == ' ' && sb.charAt(i + 1) != ' ') {
                rev.append(' ');
            }
        }
        //初始化双指针
        int start = 0;
        int end = rev.length();
        //翻转每个单词
        for (int i = 0; i < rev.length(); i++) {
            if (rev.charAt(i) == ' ' ||  i == rev.length() - 1) {//最后一个单词特判
                end = i == rev.length() - 1 ? i : i - 1;//最后一个单词特判
                while (start <= end) {//每个单词中,双指针swap
                    char tmp = rev.charAt(end);
                    rev.setCharAt(end, rev.charAt(start));
                    rev.setCharAt(start, tmp);
                    start++;
                    end--;
                }
                start = i + 1;//更新下一个单词的start, 为空格后一位
            }
        }
        return rev.toString();
    }
}