题目链接:https://leetcode.com/problems/reverse-words-in-a-string/
题目:
Given an input string, reverse the string word by word.
For example,
Given s = "the sky is blue",
return "blue is sky the".
Update (2015-02-12):
For C programmers: Try to solve it in-place in O(1) space.
click to show clarification.
Clarification:
What constitutes a word?
A sequence of non-space characters constitutes a word.
Could the input string contain leading or trailing spaces?
Yes. However, your reversed string should not contain leading or trailing spaces.
How about multiple spaces between two words?
Reduce them to a single space in the reversed string.
解题思路:
这道题在实际工程中经常遇到,还好只用空格分隔,没有别的奇奇怪怪的符号,否则要用正则表达式了。
思路是这样的:
1. 将字符串以空格 split 成一个字符串数组,注意:若有两个空格连在一起,那用空格拆分后会出现一个空字符串,可以看成是两个空格之间存在一个空串
2. 用 StringBuilder 将字符串数组中的字符串逆序放到 StringBuilder 中,单词之间插入空格。代码中采用 insert(int index, String str) 方法将顺序的字符串插入到第 0 个位置。注意:StringBuilder 最后可能多一个空格,要将空格删除
3. 最后将 StringBuilder 转成 String 即可
大神提供另一种思路:http://blog.youkuaiyun.com/linhuanmars/article/details/20982463
思路是
1. 先把整个串反转并且同时去掉多余的空格
2. 然后再对反转后的字符串对其中的每个单词进行反转,比如”the sky is blue”,先反转成”eulb si yks eht”,然后在对每一个单词反转,得到”blue is sky the”。
3. 这种方法先反转的时间复杂度是O(n),然后再对每个单词反转需要扫描两次(一次是得到单词长度,一次反转单词),所以总复杂度也是O(n),比起上一种方法并没有提高,甚至还多扫描了一次,不过空间上这个不需要额外的存储一份字符串,不过从量级来说也还是O(n)。
两种方法并没有哪种有明显优势。之所以列出第二种方法是因为有些题用这种方法确实不错,有时候可以借鉴一下这个想法,就是先反转整体,再反转局部。比如说左旋转一个数组,用这种方法可以用常量空间搞定。
代码实现:
public class Solution {
public String reverseWords(String s) {
if(s == null || s.length() == 0)
return s;
String[] words = s.split(" ");
StringBuilder sb = new StringBuilder();
for(String word : words) {
if(word.length() == 0)
continue;
sb.insert(0, word);
sb.insert(0, " ");
}
if(sb.length() > 1)
sb.deleteCharAt(0);
return sb.toString();
}
}
22 / 22 test cases passed.
Status: Accepted
Runtime: 16 ms
大神的思路实现:
public class Solution {
public String reverseWords(String s) {
if(s==null) return null;
s = s.trim();
if(s.length()==0) return "";
StringBuilder res = new StringBuilder();
for(int i=s.length()-1; i>=0; i--){
if(i!=s.length()-1 && s.charAt(i)==' ' && s.charAt(i)==s.charAt(i+1)) continue;
res.append(s.charAt(i));
}
int left=0;
int right=0;
while(right<res.length()){
while(right<res.length() && res.charAt(right)!=' '){
right++;
}
int next = right+1;
right--;
while(left<right){
char temp = res.charAt(left);
res.setCharAt(left++, res.charAt(right));
res.setCharAt(right--, temp);
}
left = next;
right = next;
}
return res.toString();
}
}
22 / 22 test cases passed.
Status: Accepted
Runtime: 14 ms