アルゴリズムレビュー 4 日目: ダブルポインター - 3

目次

1. 文字列を反転します

1. ダブルポインタ 

複雑さの分析

 次に、文字列 ||| 内の単語を反転します。

1. 余分なスペースを使用する

アイデアとアルゴリズム

複雑さの分析

2. 現場での解決策

アイデアとアルゴリズム

複雑さの分析

1. 文字列を反転します

344. 文字列を反転する - LeetCode https://leetcode.cn/problems/reverse-string/

1. ダブルポインタ 

 

class Solution {
public:
    void reverseString(vector<char>& s) {
        int n = s.size();
        for (int left = 0, right = n - 1; left < right; ++left, --right) {
            swap(s[left], s[right]);
        }
    }
};

複雑さの分析

時間計算量: O(N)、NN は文字配列の長さです。合計 N/2 回の交換が実行されます。
空間複雑度: O(1)。複数の変数を格納するには定数スペースのみが使用されます。

 次に、文字列 ||| 内の単語を反転します。

557. 文字列内の単語を反転する III - LeetCode https://leetcode.cn/problems/reverse-words-in-a-string-iii/

1. 余分なスペースを使用する

アイデアとアルゴリズム

新しい文字列を作成します。次に、元の文字列を最初から最後までスペースが見つかるまでたどると、単語が見つかり、その単語の開始位置と終了位置を取得できます。次に、単語の開始位置と終了位置に従って、その単語を新しい文字列に逆の順序で配置できます。このループは、元の文字列が走査され、反転された結果が得られるまで、数回繰り返されます。

class Solution {
public:
    string reverseWords(string s) {
        string ret;
        int length = s.length();
        int i = 0;
        while (i < length) {
            int start = i;
            while (i < length && s[i] != ' ') {
                i++;
            }
            for (int p = start; p < i; p++) {
                ret.push_back(s[start + i - 1 - p]);
            }
            while (i < length && s[i] == ' ') {
                i++;
                ret.push_back(' ');
            }
        }
        return ret;
    }
};

複雑さの分析

時間計算量: O(N)、NN は文字列の長さです。元の文字列の各文字は、O(1) 時間以内に新しい文字列に入れられます。

空間の複雑さ: O(N)。元の文字列と同じ大きさのスペースを空けます。

2. 現場での解決策

アイデアとアルゴリズム

この質問は、追加のスペースのオーバーヘッドを避けるために、元の文字列に対して直接操作することもできます。単語が見つかったら、文字列の最初の文字と最後から 2 番目の文字を交換し、次に 2 番目の文字と最後から 2 番目の文字を交換します...というように、元の空間で単語を反転します。

一部の言語 (Java、JavaScript など) では String 型が不変型であるため、インプレース ソリューションは適用できないことに注意してください。

class Solution {
public: 
    string reverseWords(string s) {
        int length = s.length();
        int i = 0;
        while (i < length) {
            int start = i;
            while (i < length && s[i] != ' ') {
                i++;
            }

            int left = start, right = i - 1;
            while (left < right) {
                swap(s[left], s[right]);
                left++;
                right--;
            }
            while (i < length && s[i] == ' ') {
                i++;
            }
        }
        return s;
    }
};

 左右の 2 つのポインターを直接定義することもできます。

複雑さの分析

時間計算量: O(N)。文字列内の各文字は、O(1) 時間以内に対応する位置に交換されるか、スペースであるため変更されないままになります。

空間複雑度: O(1)。追加の配列を開く必要がないためです。

おすすめ

転載: blog.csdn.net/m0_63309778/article/details/126582894