面试题 58.1:翻转单词顺序列

别来无恙 提交于 2020-02-29 00:26:45

题目描述

牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

思路

先把句子中的所有字符进行翻转,再翻转每个单词中字符的顺序。

翻转每个单词时,添加两个指针,分别指向单词的第一个字符和单词的最后一个字符。

当第一个指针指向空格时,两个指针都前进一步。

否则判断第二个指针是是否到单词的最后一个字符了,到了则翻转,之后将两个指针分别前进一步指向空格。

否则说明还没到单词结尾,第二个指针继续前进一步。

这里第二个指针判断时需要注意索引越界以及是否已到结尾。

代码

public class Solution {
    public String ReverseSentence(String str) {
        if (str == null || str.length() == 0) {
            return "";
        }
        
        // 如果就是一个单词,不是句子
        if (!str.contains("")) {
            return str;
        }
        
        char[] charArray = str.toCharArray();
        int length = charArray.length;
        
        // 将整个句子进行翻转
        reverse(charArray, 0, length - 1);
        
        // 标记单词的第一个字符
        int left = 0;
        // 标记单词的最后一个字符
        int right = 0;
        
        // 找到单词,并翻转
        while (left < length) {
            // 如果指向的是空格
            if (charArray[left] == ' ') {
                left++;
                right++;
            } else if ((right < length - 1 && charArray[right + 1] == ' ') 
                      || right == length - 1) {
                // 当第二个指针的下一个字符是空格,说明已经到单词结尾
                // 或者第二个指针已经到句子结尾了,那么就可以翻转了
                reverse(charArray, left, right);
                // 两个指针指向单词后面的字符
                right++;
                left = right;
            } else { // 还没找到单词,第二个指针直接加 1
                right++;
            }
        }
        
        return new String(charArray);
    }
    
    private void reverse(char[] arr, int left, int right) {
        char ch;
        while (left < right) {
            ch = arr[left];
            arr[left] = arr[right];
            arr[right] = ch;
            left++;
            right--;
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!