题目
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
解析
预备知识
题目的意思给定一个字符串,把其中所有的单词倒序输出,且保持原有的空格数。
有的人可能要用split分割出所有的单词,然后倒序组成字符串即可。这样做有1个缺点,一是split会丢失末尾空格,所以需要做特殊处理。
思路一
既然要翻转单词序列,我们不妨整体字符串做一次翻转,比如原字符串为:I love you
,整体翻转后为:uoy evol I
, 很显然句子是按着题目的意思翻转了过来,但是里面的单词都是倒序了,所以我们只需再对每一个单词做一次翻转即可。比如uoy
,翻转后为you
。
public static String ReverseSentence2(String str) {
if(str == null || str.equals("")) {
return str;
}
char[] chars = str.toCharArray();
reverse(chars, 0, str.length() - 1);
int start = 0;
for(int i = 0; i < chars.length; i++) {
if(chars[i] != ' ') {
start = i;
while((++i) < chars.length && chars[i] != ' ');
reverse(chars, start, i - 1);
}
}
return new String(chars);
}
public static void reverse(char[] chars, int start, int end) {
for(int i = start, j = end; i < j; i++, j--) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
}
思路二
假设result为目标输出结果,我们可以找出遍历字符串中所有的单词,然后不断的把这个单词加到result之前,这样最后一个单词肯定在最前面了,而原句子中第一个单词则将出现在最后。
可能会疑问前缀空格和后缀空格如何处理,我们这里规定只要碰到一个空格,当将该空格之前字符认为是一个单词,这样就可以有效的解决前缀出现空格情况。
递归版
public static String ReverseSentence(String str) {
return str.lastIndexOf(" ") == -1 ? str : str.substring(str.lastIndexOf(" ") + 1)
+ " " + ReverseSentence(str.substring(0, str.lastIndexOf(" ")));
}
非递归版
public static String ReverseSentence3(String str) {
if(str == null || str.equals("")) {
return str;
}
StringBuilder sb = new StringBuilder();
StringBuilder temp = new StringBuilder();
for(int i = 0; i < str.length(); i++) {
if(str.charAt(i) == ' ') {
sb.insert(0, temp.toString());
sb.insert(0, " ");
temp.delete(0, temp.length());
} else {
temp.append(str.charAt(i));
}
}
sb.insert(0, temp.toString());
return sb.toString();
}
总结
多写多画即可。