Code Capriccio - String - Reverse the words in the string

Reverse words in a string

This section corresponds to Code Random Notes: Code Random Notes , explanation video: Complex string operations are mastered! | LeetCode:151. Flip the words in the string_bilibili_bilibili

exercise

Question link: 151. Reverse words in a string - LeetCode

Given a string s, please reverse the order of the words in the string.

A word is a string of non-space characters. Use at least one space in s to separate the words in the string.

Returns the resulting string with the words in reverse order and concatenated with single spaces between words.

Note: There may be leading spaces, trailing spaces, or multiple spaces between words in the input string s. The returned result string should have words separated by only single spaces and should not contain any additional spaces.

示例 2:
输入:s = "  hello world  "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。

My solution

There are two difficulties in solving this problem. One is to reverse the words in the string, and the other is to remove extra spaces.

For reversing words, you can first reverse the string, and then reverse each word in it, thus reversing the order of the words in the string. Specifically, traverse the string and use a variable lastto always record the position of the first character of the word. When a space is encountered or the next position of the string is reached, the previous word is reversereversed using the function

The difficult or optimizable point is to remove redundant spaces. My solution is to use a while loop to traverse the string, and when a space is encountered, use a while loop to search backward from the current position until a non-empty character is encountered. This determines a continuous string of spaces. eraseAfter deleting this string using the function, another space must be inserted at the beginning to act as a space between words.

class Solution {
    
    
   public:
    // 去除多余空格
    void removeExtraSpaces(string& s) {
    
    
        int cur = 0;
        while (cur < s.size()) {
    
    
            if (s[cur] == ' ') {
    
    
                int tmp = cur;
                while (s[cur] == ' ') {
    
    
                    cur++;
                }
                s.erase(tmp, cur - tmp);
                // 删除空格字符串后,cur指针位置也要前移到之前第一个空格的位置
                cur = tmp; 
                if (tmp != 0 && tmp != s.size())
                    s.insert(tmp, 1, ' ');
            }
            cur++;
        }
    }
    string reverseWords(string s) {
    
    
        removeExtraSpaces(s);
        // 反转单词
        int last = 0;
        reverse(s.begin(), s.end());
        for (int i = 0; i <= s.size(); i++) {
    
    
	        // 字符串最后一个字符不是空格时也要反转
            if (s[i] == ' ' || i == s.size()) {
    
    
                reverse(s.begin() + last, s.begin() + i);
                last = i + 1;
            }
        }
        return s;
    }
};
  • Time complexity: O( n 2 n^2n2 ). where n is the length of string s. Mainly in the removeExtraSpaces function, because the time complexity of the erase operation and the insertion operation is O(n), and the number of loop nestings may also be O(n) level. In the process of string reversal, the STL library function reverse is applied, and the time complexity is O(n), so the overall time complexity is O(n^2)
  • Space complexity: O( 1 11 ). No extra space is used to store data, only modifications are made to the original string, so the space complexity is constant level

double pointer

The double pointer solution to reverse words is the same as my solution above, but the process of removing spaces is optimized. My solution above is to use two while loops to remove spaces, and the double pointer method is similar to the problem of removing elements from an array. This is equivalent to removing spaces, except that after removing spaces, you have to manually add spaces between words.

Use the fast pointer to traverse the string, and the slow pointer to reassign s. When the fast pointer traverses to a space that is not equal to a space, the slow pointer is operated to assign the current word to the appropriate position of s. Again, spaces between words need to be added manually each time.

I didn't expect this method when I wrote it. Sure enough, many times when operating strings and arrays, double pointers can be used for optimization.

class Solution {
    
    
   public:
    // 整体思想参考https://programmercarl.com/0027.移除元素.html
    // 去除所有空格并在相邻单词之间添加空格, 快慢指针。
    void removeExtraSpaces(string& s) {
    
    
        int slow = 0;
        for (int i = 0; i < s.size(); ++i) {
    
    
            if (s[i] != ' ') {
    
    
                // 字符串的起始不用加空格
                if (slow != 0)
                    s[slow++] = ' ';
                // 将新的单词赋给s
                while (i < s.size() && s[i] != ' ') {
    
    
                    s[slow++] = s[i++];
                }
            }
        }
        s.resize(slow);  // slow的大小即为去除多余空格后的大小。
    }
    string reverseWords(string s) {
    
    
        removeExtraSpaces(s);
        int last = 0;
        reverse(s.begin(), s.end());
        for (int i = 0; i <= s.size(); i++) {
    
    
            if (s[i] == ' ' || i == s.size()) {
    
    
                reverse(s.begin() + last, s.begin() + i);
                last = i + 1;
            }
        }
        return s;
    }
};
  • Time complexity: O( nnn ). where n is the length of string s. Mainly in the removeExtraSpaces function, the double pointer method is used to remove excess spaces, and the time complexity is O(n). In the process of reversing words, the STL library function reverse is used, and the time complexity is also O(n), so the overall The time complexity is O(n)
  • Space complexity: O( 1 11 ). No extra space is used to store data, only modifications are made to the original string, so the space complexity is constant level

Guess you like

Origin blog.csdn.net/zss192/article/details/129889087