题目描述
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。
思路
思路1:考察字符串翻转。该题需要两次翻转,以输入字符串"I am a student. "为例。
- Step1.先翻转整个句子,得到".tneduts a ma I"
- Step2.再翻转句中每个单词,得到"student. a am I"。
需要注意的是,要对句子最后一个单词单独翻转。另外,牛客测试用例不用考虑删除多个空格,而力扣需要考虑。以下解法暂不考虑删除多余的空格。
特殊测试用例:字符串中只有空格。
思路2:使用str.split(
" "
)将一个字符串分成多个,再反向添加。
解法1.1(手写reverse)
public class Solution { /* * 先翻转整个句子,然后,依次翻转每个单词。 * 依据空格来确定单词的起始和终止位置,最后一个单词要单独处理 */ public String ReverseSentence(String str) { if (str == null || str.length() == 0) return str; char[] chars = str.toCharArray(); reverse(chars,0,str.length()-1); // Step1.先翻转整个句子 int index = 0; for (int i = 0; i < chars.length; i++) { //Step2.再翻转句中每个单词 if (chars[i] == ' '){ reverse(chars,index,i - 1); index = i + 1; }else if ((i == chars.length - 1)){ // 最后一个单词要单独翻转。 reverse(chars,index,i); // 或者要考虑到特例,一个句子只有一个单词,那么也就没有空格。 } } return String.valueOf(chars); } private void reverse(char[] chars,int start, int end){ while (start < end){ char temp = chars[start]; chars[start] = chars[end]; chars[end] = temp; start++; end--; } } }
解法1.2(调用API)
public class Solution { public String ReverseSentence(String str) { // 注意测试用例要考虑到字符串中全为空格的情况;String.trim():去掉字符串首尾的空格。 if (str == null || str.length() == 0 || str.trim().length() ==0) return str; String flipStr = new StringBuilder(str).reverse().toString(); // 对整个句子翻转 StringBuilder res = new StringBuilder(); // 用来保存结果 StringBuilder temp = new StringBuilder(); // 用来遍历每个单词 for (int i = 0; i < flipStr.length(); i++) { if (flipStr.charAt(i) == ' '){ //对每个单词翻转(给出两种添加方式) //res.append(res.length() == 0 ? temp.reverse().toString() : " "+temp.reverse()); //在每个单词前添加空格 res.append(temp.reverse().toString()).append(" "); // 在每个单词后加空格 temp = new StringBuilder(); // 初始化 }else{ temp.append(flipStr.charAt(i)); } } // 最后那个单词单独处理 res.append(temp.reverse().toString()); //res.append(res.length() == 0 ? temp.reverse().toString() : " "+temp.reverse()); return res.toString(); } }
解法2
public class Solution { public String ReverseSentence(String str) { if (str == null || str.length() == 0 || str.trim().length() ==0)//需要将多个空格的情况考虑进来 return str; StringBuilder sb = new StringBuilder(); String[] strSet = str.split(" "); //将一个字符串分成多个单词后,装数组里 for (int i = strSet.length - 1; i > 0; i--) { sb.append(strSet[i] + " "); //从尾部添加就可以保证顺序颠倒了 } sb.append(strSet[0]);//写在外面是因为最后一个添加的不用添加空格了。 return sb.toString(); } }
参考:
《剑指offer》 第58.1题 翻转字符串之翻转单词顺序