Sword finger [58] - flip the order of words

Title Source: Sword finger Offer 58 - I. flip word order
Title Description:

Input an English sentence and flip the order of words in the sentence, but the order of characters in the word remains the same. For simplicity, punctuation is treated like ordinary letters. For example, enter a string"I am a student. ",Then output"student. a am I". 

Example 1:
input: "the sky is blue"
output: "blue is sky the"
 
Example 2:
input: "  hello world!  "
output: "world! hello"
explain: The input string can contain extra spaces before or after, but the inverted characters cannot be included.

Example 3:
input: "a good   example"
output: "example good a"
explain: If there is extra space between two words, reduce the space between words after inversion to only one.
 

explain:
Characters without spaces form a word.
The input string can contain extra spaces before or after, but the inverted characters cannot be included.
If there is extra space between two words, reduce the space between words after inversion to only one.

Use the method of cutting strings into arrays;

class Solution {
    public String reverseWords(String s) {
        //First delete the spaces before and after; Use split to cut the string into an array divided by one or more spaces;
        String[] strArray = s.trim().split(" +");
        //Returned string sb;
        StringBuilder sb = new StringBuilder();
        //Concatenate the words of the array in reverse order;
        for (int i = strArray.length - 1; i >= 0; i--) {
            sb.append(strArray[i]);
            //Add spaces when filling in each word;
            sb.append(" ");
            //When the first word is reached, cancel the space;
            if(i == 0){
                //Delete the last space;
                sb.delete(sb.lastIndexOf(" "),sb.length());
            }
        }
        return sb.toString();
    }
}

Poor efficiency;

Try with a case; Use the string "a good example";
It will not contain extra spaces in the separated array, because the first step is to separate the array with spaces; split("+") is used; Matches one or more spaces;
So with this in mind, you should add a space after each word when returning; But the last word (that is, the first word of the original string) is special; You can't add a space after it. I deleted the space with the delete method;

Optimize the method of cutting strings into arrays;

class Solution {
   public String reverseWords(String s) {
        //Delete only the spaces before and after; Use split to cut the string into an array divided by spaces;
        String[] strArray = s.trim().split(" ");
        //Returned string sb;
        StringBuilder sb = new StringBuilder();
        //Concatenate the words of the array in reverse order;
        for (int i = strArray.length - 1; i >= 0; i--) {
            //If the array element is empty, skip it directly;
            if (strArray[i].equals("")) {
                continue;
            }else{
               sb.append(strArray[i]);
            //Add spaces when filling in each word;
            sb.append(" "); 
            }
        }
        //Finally, when returning, delete the redundant spaces on both sides;
        return sb.toString().trim();
    }
}

Implementation efficiency has improved

At the beginning of this optimization, all spaces in the string are not cleared;
Separate strings by a single space only; Then, the array elements with spaces may appear in the obtained array;
Then you have to consider skipping these elements during operation;
Finally, there are redundant spaces after the last word; Then you can clear the return area with trim();

Use left and right pointers;

(1) The left pointer moves to the left first; When returning, intercept the string from the last bit of the left pointer to the last bit of the right pointer

(2) The left pointer continues to move to the left; Skip when you encounter spaces; Until the word character is found, connect the right pointer;

(3) Then the left pointer moves to the left first, and stops after finding a space; Intercept this string;

(4) At this time, the left pointer continues to move to the left, finds the character a, and connects the right pointer;

(5) Intercept the characters from the left pointer to the right pointer; Splice the past; At this time, notice that the left pointer has reached - 1 and jump out of the loop

(6) It is found that there is one more space in the last bit of the returned string; Then consider deleting this space; Then return;

class Solution {
    public  String reverseWords(String s) {
        //Clear the space around the string first;
        s = s.trim();
        //Returned string;
        StringBuilder sb = new StringBuilder();

        //At first, the left and right pointers are on the right of the string;
        int left = s.length() - 1, right = s.length() - 1;

        //Let the left pointer move left to find a space;
        while (left >= 0) {
            //The left pointer moves continuously from right to left, looking for the first space first;
            while (left >= 0 && s.charAt(left) != ' '){
                left--;
            }
            //After finding, add the string after the space to the returned string; And splice a space;
            //Note that the string interception method substring(int start,int end) is left closed and right open;
            sb.append(s.substring(left + 1, right + 1)).append(" ");

            //When the left pointer moves to the left, if it matches a space, it will skip;
            while (left >= 0 && s.charAt(left) == ' '){
                left--;
            }
            //The left pointer finds a character that is not a space; Move the right pointer to the position of the left pointer;
            right = left;
        }
        return sb.toString().trim();
    }
}    

The left pointer finds the position of words and characters, and then connects the right pointer to use;

Posted on Sat, 20 Nov 2021 13:10:07 -0500 by Cagez