[LeetCode]151. 翻转字符串里的单词

题目

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。

示例 1:

输入: "the sky is blue"
输出: "blue is sky the"
示例 2:

输入: "  hello world!  "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:

输入: "a good   example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

原地翻转(方法一):
两次翻转

构建新的串(方法二):
双指针倒着遍历,把单词加到目标字符串中。
这里对于结尾单词和遇到‘ ’而得到的单词统一处理做的比较好。

代码

方法一(通过牛客该题)

public class Solution {
    public String ReverseSentence(String str) {
        if(str == null || str.trim().equals("")){
            return str;
        }
        
        char[] chars = str.trim().toCharArray();
        reverse(chars, 0, chars.length - 1);
        int blank = -1;
        for(int i = 0; i < chars.length; ++i){
            if(chars[i] == ' '){
                reverse(chars, blank + 1, i - 1);
                blank = i;
            }
        }
        reverse(chars, blank + 1, chars.length - 1);
        return new String(chars);
    }
    
    private void reverse(char[] chars, int l, int r){
        while(l < r){
            char temp = chars[l];
            chars[l] = chars[r];
            chars[r] = temp;
            l++;
            r--;
        }
    }
}

方法二(通过LeetCode该题)

class Solution {
	public String reverseWords(String s) {
		String str = s.trim();
		int j = str.length() - 1;
		int i = j;
		StringBuilder res = new StringBuilder();

		while (i >= 0) {
			while (i >= 0 && str.charAt(i) != ' ') {
				--i;
			}// 倒着找到第一个空格 或 i=-1即字符串起始位置-1=>找到目标单词的左边界
			res.append(str.substring(i + 1, j + 1) + " "); //将结尾单词/遇到空格单词统一处理
			while (i >= 0 && str.charAt(i) == ' ') {
				--i;
			}// 过掉所有的空格=>找到目标单词的右边界
			j = i;
		}

		return res.toString().trim();
	}
}
原文地址:https://www.cnblogs.com/coding-gaga/p/12357095.html