说明
算法:Reverse Words in a String
LeetCode地址:https://leetcode.com/problems/reverse-words-in-a-string/
题目:
Given an input string, reverse the string word by word.
Example 1:
Input: "the sky is blue"
Output: "blue is sky the"
Example 2:
Input: " hello world! "
Output: "world! hello"
Explanation: Your reversed string should not contain leading or trailing spaces.
Example 3:
Input: "a good example"
Output: "example good a"
Explanation: You need to reduce multiple spaces between two words to a single space in the reversed string.
Note:
- A word is defined as a sequence of non-space characters.
- Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces.
- You need to reduce multiple spaces between two words to a single space in the reversed string.
Follow up:
For C programmers, try to solve it in-place in O(1) extra space.
解题思路1
翻转字符串里的单词, split()
先把单词拆解为wordsArray,倒序把word拼接即可。
时间复杂度为 O(N); 空间复杂度为O(N).
代码实现1
import java.util.Arrays;
public class ReverseWordsInAString {
public String reverseWords(String s) {
s = s.trim();
if (s.length() == 0) {
return s;
}
String blankString = " ";
String[] wordsArray = s.split(blankString);
StringBuilder sb = new StringBuilder();
for (int i = wordsArray.length - 1; i >= 0; i--) {
String word = wordsArray[i];
word = word.trim();
if (word.length() > 0) {
sb.append(word).append(blankString);
}
}
return sb.toString().trim();
}
public static void main(String[] args) {
String input = "the sky is blue";
ReverseWordsInAString obj = new ReverseWordsInAString();
System.out.println("Input: \"" + input + "\"\n" + "Output: \"" + obj.reverseWords(input) + "\"") ;
String input1 = " hello world! ";
System.out.println("Input: \"" + input1 + "\"\n" + "Output: \"" + obj.reverseWords(input1) + "\"") ;
String input2 = "a good example";
System.out.println("Input: \"" + input2 + "\"\n" + "Output: \"" + obj.reverseWords(input2) + "\"") ;
}
}
运行结果1
Input: "the sky is blue"
Output: "blue is sky the"
Input: " hello world! "
Output: "world! hello"
Input: "a good example"
Output: "example good a"
代码执行效率1
Runtime: 2 ms, faster than 92.72% of Java online submissions for Reverse Words in a String.
Memory Usage: 38.5 MB, less than 66.81% of Java online submissions for Reverse Words in a String.
解题思路2
降低空间复杂度,把字符串转为字符数组 > 字符数组原地翻转 > 找到单词在word内部翻转回来 > 清理多余的空字符并替换掉前面的字符 > 新建字符串,截取到前面有效字符。
时间复杂度为 O(N),空间复杂度也为O(N), 但是前面的系数明显会小于上面的。
代码实现2
import java.util.Arrays;
public class ReverseWordsInAString {
public String reverseWordsWithLessSpace(String s) {
char[] chars = s.toCharArray();
int len = chars.length;
// step 1. reverse the whole string
subReverse(chars, 0, len - 1);
// step 2. reverse each word
subReverseWords(chars, len);
// step 3. clean up spaces
return subCleanBlankChar(chars, len);
}
// trim leading, trailing and multiple spaces
public String subCleanBlankChar(char[] chars, int len) {
int i = 0, j = 0;
char blankChar = ' ';
while (j < len) {
// skip spaces
while (j < len && chars[j] == blankChar) {
j++;
}
// keep non spaces
while (j < len && chars[j] != blankChar) {
chars[i++] = chars[j++];
}
// skip spaces
while (j < len && chars[j] == blankChar) {
j++;
}
// keep only one space
if (j < len) {
chars[i++] = blankChar;
}
}
return new String(chars).substring(0, i);
}
public void subReverseWords(char[] chars, int len) {
char blankChar = ' ';
int i = 0, j = 0;
while (j < len) {
// skip spaces
while (j < len && chars[j] == blankChar) {
j++;
}
i = j;
// skip non spaces
while (j < len && chars[j] != blankChar) {
j++;
}
// reverse the word
subReverse(chars, i, j - 1);
}
}
// reverse a[] from a[i] to a[j]
public void subReverse(char[] chars, int startIndex, int endIndex) {
while (startIndex < endIndex) {
char temp = chars[startIndex];
chars[startIndex] = chars[endIndex];
chars[endIndex] = temp;
startIndex++;
endIndex--;
}
}
public static void main(String[] args) {
String input = "the sky is blue";
ReverseWordsInAString obj = new ReverseWordsInAString();
System.out.println("Input: \"" + input + "\"\n" + "Output: \"" + obj.reverseWordsWithLessSpace(input) + "\"") ;
String input1 = " hello world! ";
System.out.println("Input: \"" + input1 + "\"\n" + "Output: \"" + obj.reverseWordsWithLessSpace(input1) + "\"") ;
String input2 = "a good example";
System.out.println("Input: \"" + input2 + "\"\n" + "Output: \"" + obj.reverseWordsWithLessSpace(input2) + "\"") ;
}
}
运行结果2
Input: "the sky is blue"
Output: "blue is sky the"
Input: " hello world! "
Output: "world! hello"
Input: "a good example"
Output: "example good a"
代码执行效率2
Runtime: 4 ms, faster than 71.55% of Java online submissions for Reverse Words in a String.
Memory Usage: 37.7 MB, less than 83.83% of Java online submissions for Reverse Words in a String.
总结
翻转字符串里的单词,第一种方案:拆分单词数组,倒序拼接最直接,也是最快的。第二种方案:减少空间复杂度,用到字符数组原地排序的技巧。