【アルゴリズムのブレークスルー】ダブルポインタ - ゼロの上書き (2)

目次

1. トピック分析

2. アルゴリズム原理

3. コードの書き方

最後に次のように書きます。


1. トピック分析

トピックリンク: 1089. ゼロの上書き - Leetcode

まずはタイトルを読んでいきますが、

タイトルの意味は実はとてもシンプルで、

0 が見つかった場合は、1 つをコピーして配列に書き込み、右側の要素を 1 ビット右にシフトします。

例題を見ると質問の意味が理解しやすいです。 

2. アルゴリズム原理

一般に、配列の要素を移動する必要があるような質問は、

ダブル ポインター演算も、問題を解決するために非常によく使用されます。

この質問がインプレース アルゴリズムを使用しない場合、質問は非常に単純になります。

元の配列をトラバースするポインタ、新しい配列をトラバースするポインタ、

非ゼロに遭遇した場合は、それを配列に直接書き込み、0 に遭遇した場合は配列に 2 つの 0 を書き込みます。

このアルゴリズムをインプレースで最適化したい場合はどうすればよいでしょうか?

左から右に試してみましょう。

 うまくいきそうにありません:

元の数値が変更されているため、すべてが 0 にコピーされる状況が発生します。

次に、後ろから前に向かって考えてみましょう。

cur が最後の書き込みの場所を指すようにします。

次に、ダブル ポインターのプロセスをシミュレートします。

cur が 0 に遭遇すると、2 回コピーされます。

 

非ゼロに遭遇した場合は通常どおりに書き込みます。

等々:

 私たちは成功したことがわかりました、

ここで問題は、cur の開始位置をどのように取得するかです。

あるいは、最後の書き込みの場所を取得するにはどうすればよいでしょうか?

2 つのポインター cur と dest を使用して、ダブル ポインターを再度記述するプロセスをシミュレートできます。

1. 現在の位置が 0 であるか非ゼロであるかを判断します。

2. dest は、cur 位置の値に従って 1 歩または 2 歩進むことを決定します。

3. destが最後に到達したかどうかを確認します

4. 末尾に到達していない場合は cur++、末尾に到達している場合は、cur が指す位置が最後に書き込まれた番号になります。

ただし、dest の範囲外の問題に注意してください。最後から 2 番目の番号に達したときに cur が 0 になった場合、

destが2歩後退すると、境界を越えるという問題が発生します。時間が来たら、cur は 1 歩下がり、dest は 2 歩下がります。

3. コードの書き方

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int dest = -1, cur = 0, size = arr.size();
        // 找到最后一次写入的位置
        while(cur < size) {
            if(arr[cur]) dest++;
            else dest += 2;
            if(dest >= size - 1) break; //走完了
            cur++;
        }
        // 控制边界
        if(dest == size) { //这种就是最后一步是0,走了两步dest越界的情况
            arr[size - 1] = 0;
            dest -= 2;
            cur--;
        }
        // 从后往前做写入操作
        while(cur >= 0) {
            if(arr[cur]) arr[dest--] = arr[cur--];
            else {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
        }
    }
};

最後に次のように書きます。

以上が今回の記事の内容となります、読んでいただきありがとうございます。

何かを得たと感じたら、ブロガーに「いいね! 」を与えることができます。

記事の内容に抜けや間違いがある場合は、ブロガーにプライベートメッセージを送信するか、コメントエリアで指摘してください〜

おすすめ

転載: blog.csdn.net/Locky136/article/details/131537158