算法:Reverse Words in a String(翻转字符串里的单词)

说明

算法:Reverse Words in a String
LeetCode地址:https://leetcode.com/problems/reverse-words-in-a-string/

题目:
Given an input string, reverse the string word by word.

Example 1:

Input: "the sky is blue"
Output: "blue is sky the"

Example 2:

Input: "  hello world!  "
Output: "world! hello"
Explanation: Your reversed string should not contain leading or trailing spaces.

Example 3:

Input: "a good   example"
Output: "example good a"
Explanation: You need to reduce multiple spaces between two words to a single space in the reversed string.

Note:

  • A word is defined as a sequence of non-space characters.
  • Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces.
  • You need to reduce multiple spaces between two words to a single space in the reversed string.

Follow up:

For C programmers, try to solve it in-place in O(1) extra space.

解题思路1

翻转字符串里的单词, split() 先把单词拆解为wordsArray,倒序把word拼接即可。
时间复杂度为 O(N); 空间复杂度为O(N).

代码实现1

import java.util.Arrays;

public class ReverseWordsInAString {

    public String reverseWords(String s) {
        s = s.trim();
        if (s.length() == 0) {
            return s;
        }
        String blankString = " ";
        String[] wordsArray = s.split(blankString);
        StringBuilder sb = new StringBuilder();

        for (int i = wordsArray.length - 1; i >= 0; i--) {
            String word =  wordsArray[i];
            word = word.trim();
            if (word.length() > 0) {
                sb.append(word).append(blankString);
            }
        }

        return sb.toString().trim();
    }

	public static void main(String[] args) {
        String input = "the sky is blue";
        ReverseWordsInAString obj = new ReverseWordsInAString();
        System.out.println("Input: \"" + input + "\"\n" + "Output: \"" + obj.reverseWords(input) + "\"") ;

        String input1 = "  hello world!  ";
        System.out.println("Input: \"" + input1 + "\"\n" + "Output: \"" + obj.reverseWords(input1) + "\"") ;

        String input2 = "a good   example";
        System.out.println("Input: \"" + input2 + "\"\n" + "Output: \"" + obj.reverseWords(input2) + "\"") ;
    }
}

运行结果1

Input: "the sky is blue"
Output: "blue is sky the"
Input: "  hello world!  "
Output: "world! hello"
Input: "a good   example"
Output: "example good a"

代码执行效率1

Runtime: 2 ms, faster than 92.72% of Java online submissions for Reverse Words in a String.
Memory Usage: 38.5 MB, less than 66.81% of Java online submissions for Reverse Words in a String.

解题思路2

降低空间复杂度,把字符串转为字符数组 > 字符数组原地翻转 > 找到单词在word内部翻转回来 > 清理多余的空字符并替换掉前面的字符 > 新建字符串,截取到前面有效字符。
时间复杂度为 O(N),空间复杂度也为O(N), 但是前面的系数明显会小于上面的。

代码实现2

import java.util.Arrays;

public class ReverseWordsInAString {

    public String reverseWordsWithLessSpace(String s) {
        char[] chars = s.toCharArray();
        int len = chars.length;
        // step 1. reverse the whole string
        subReverse(chars, 0, len - 1);
        // step 2. reverse each word
        subReverseWords(chars, len);
        // step 3. clean up spaces
        return subCleanBlankChar(chars, len);
    }

    // trim leading, trailing and multiple spaces
    public String subCleanBlankChar(char[] chars, int len) {
        int i = 0, j = 0;
        char blankChar = ' ';
        while (j < len) {
            // skip spaces
            while (j < len && chars[j] == blankChar) {
                j++;
            }
            // keep non spaces
            while (j < len && chars[j] != blankChar) {
                chars[i++] = chars[j++];
            }
            // skip spaces
            while (j < len && chars[j] == blankChar) {
                j++;
            }
            // keep only one space
            if (j < len) {
                chars[i++] = blankChar;
            }
        }

        return new String(chars).substring(0, i);
    }

    public void subReverseWords(char[] chars, int len) {
        char blankChar = ' ';
        int i = 0, j = 0;
        while (j < len) {
            // skip spaces
            while (j < len && chars[j] == blankChar) {
                j++;
            }
            i = j;
            // skip non spaces
            while (j < len && chars[j] != blankChar) {
                j++;
            }
            // reverse the word
            subReverse(chars, i, j - 1);
        }
    }

    // reverse a[] from a[i] to a[j]
    public void subReverse(char[] chars, int startIndex, int endIndex) {
        while (startIndex < endIndex) {
            char temp = chars[startIndex];
            chars[startIndex] = chars[endIndex];
            chars[endIndex] = temp;

            startIndex++;
            endIndex--;
        }
    }

	public static void main(String[] args) {
        String input = "the sky is blue";
        ReverseWordsInAString obj = new ReverseWordsInAString();
        System.out.println("Input: \"" + input + "\"\n" + "Output: \"" + obj.reverseWordsWithLessSpace(input) + "\"") ;

        String input1 = "  hello world!  ";
        System.out.println("Input: \"" + input1 + "\"\n" + "Output: \"" + obj.reverseWordsWithLessSpace(input1) + "\"") ;

        String input2 = "a good   example";
        System.out.println("Input: \"" + input2 + "\"\n" + "Output: \"" + obj.reverseWordsWithLessSpace(input2) + "\"") ;
    }
}

运行结果2

Input: "the sky is blue"
Output: "blue is sky the"
Input: "  hello world!  "
Output: "world! hello"
Input: "a good   example"
Output: "example good a"

代码执行效率2

Runtime: 4 ms, faster than 71.55% of Java online submissions for Reverse Words in a String.
Memory Usage: 37.7 MB, less than 83.83% of Java online submissions for Reverse Words in a String.

总结

翻转字符串里的单词,第一种方案:拆分单词数组,倒序拼接最直接,也是最快的。第二种方案:减少空间复杂度,用到字符数组原地排序的技巧。

代码下载:
https://github.com/zgpeace/awesome-java-leetcode/blob/master/code/LeetCode/src/popular/ReverseWordsInAString.java

猜你喜欢

转载自blog.csdn.net/zgpeace/article/details/88528127
今日推荐