Sword Finger Offer 58-I. Reverse the order of words (double pointer; multiple reversals)

Sunday, February 07, 2021, the weather is fine [Don’t lament the past, don’t waste the present, don’t fear the future]



1. Introduction

Sword Finger Offer 58-I. Reverse word order

Insert picture description here

2. Solution

2.1 Open up a new array and use double pointers to iterate from back to front

The idea of ​​this method is relatively simple, the code is easier to implement, the disadvantage is that a new array needs to be opened, and the space complexity is O(n) .

class Solution {
    
    
public:
    string reverseWords(string s) {
    
    
        int j = s.size() - 1, i = 0;
        string res;
        // 从后往前获取每个单词,在这个过程中,首尾的空格也被忽略掉了
        while(i>=0 && j>=0){
    
    
            while(j>=0 && s[j]==' ') --j;
            i = j;
            while(i>=0 && s[i]!=' ') --i;
            // 得到一个单词的首尾索引,添加到新建的字符串中
            res.append(s.substr(i+1, j-i));
            res.append(1,' ');
            j = i;
        }
        // 最后的结果尾部可能会有1个或2个空格,删除之
        j = res.size()-1;
        while(j>=0 && res[j]==' ') --j;
        return res.substr(0,j+1);
    }
};

2.2 The solution method with space complexity of O(1): first overall flip, then partial flip

First remove the spaces at the beginning and the end of the string, then turn it over as a whole, and finally turn each word partially over to get the final result. This method is slightly more complicated to implement, but the space complexity is only O(1) .

class Solution {
    
    
public:
    string reverseWords(string s) {
    
    
        if(s.empty()) return s;
        // 删除字符串首尾的空格
        trim(s);

        int n = s.size();
        // 整体翻转字符串
        reverse(s, 0, n-1);

        int i = 0, j = 0;
        while(i<n && j<n){
    
    
            // 找到一个单词的首尾,进行局部翻转
            while(j<n && s[j] != ' ') ++j;
            reverse(s, i, j-1);
            i = j;
            
            // 让i指向下一个单词的首部
            while(i<n && s[i] == ' ') ++i;
            // 删除两个单词之间的空格
            s.erase(j,i-j-1);

            // 注意!!! !!!!!!
            // 删除空格之后,字符串的长度可能发生了变化,因此i、j、n的值都要进行更新
            i = j + 1;
            j = i;
            n = s.size();
        }
        return s;
    }

    // 删除字符串首尾的空格
    void trim(string& ss){
    
    
		if (ss.empty()) return;
		int i = 0;
		while (i < ss.size() && ss[i] == ' ') ++i;
		ss.erase(0, i);

		int j = ss.size() - 1;
		while (j >= 0 && ss[j] == ' ') --j;
		ss.erase(j+1);
    }

    // 翻转字符串
    void reverse(string& ss, int beg, int end){
    
    
        if(beg<0 || beg>=ss.size() || end<0 || end>=ss.size()) return;
        while(beg<end){
    
    
            char tmp = ss[beg];
            ss[beg] = ss[end];
            ss[end] = tmp;
            ++beg;
            --end;
        }
    }
};

references

"Sword Finger Offer Second Edition"

https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/zi-jie-ti-ku-jian-58-i-jian-dan-fan-zhua-qwyg/

Guess you like

Origin blog.csdn.net/m0_37433111/article/details/113746202