ソードフィンガーオファー58-I。語順を逆にする(ダブルポインター;複数の逆)

2021年2月7日日曜日、天気は良いです[過去を嘆いたり、現在を無駄にしたり、未来を恐れたりしないでください]



1.はじめに

ソードフィンガーオファー58-I。語順を逆にする

ここに画像の説明を挿入

2.解決策

2.1新しい配列を開き、ダブルポインタを使用して後ろから前に繰り返します

このメソッドのアイデアは比較的単純で、コードは実装が簡単です。欠点は、新しい配列を開く必要があり、スペースの複雑さが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 O(1)の空間の複雑さを伴う解法:最初に全体的な反転、次に部分的な反転

最初に文字列の最初と最後のスペースを削除し、次に全体を裏返し、最後に各単語を部分的に裏返して最終結果を取得します。この方法は実装が少し複雑ですが、スペースの複雑さは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;
        }
    }
};

参照

「ソードフィンガーオファー第2版」

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 /

おすすめ

転載: blog.csdn.net/m0_37433111/article/details/113746202