剑指44.翻转单词顺序

题目描述

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"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题 翻转字符串之翻转单词顺序

 

posted @ 2020-08-26 17:52  不学无墅_NKer  阅读(192)  评论(0编辑  收藏  举报