数字の文字列を指定して、指定された文字列にサブシーケンスとして出現しない最小の非負の整数を見つけます。
0 から段階的に数を見つけるアプローチを試みましたが、私のアプローチはO(answer * length of the string)
. O(length of string)
この問題に対するアプローチはありますか?
例:
入力
- 9876543210
- 21698921085321984125
- 12345678901
出力
- 11
- 7
- 22
数字の文字列を指定して、指定された文字列にサブシーケンスとして出現しない最小の非負の整数を見つけます。
0 から段階的に数を見つけるアプローチを試みましたが、私のアプローチはO(answer * length of the string)
. O(length of string)
この問題に対するアプローチはありますか?
例:
入力
- 9876543210
- 21698921085321984125
- 12345678901
出力
- 11
- 7
- 22
このアルゴリズムに必要なデータ構造:
アルゴリズム:
代替アルゴリズム:
他の代替手段は、ほとんどの計算をステップ 4 からステップ 1 に移動することです。この場合、ビットセット配列と 10 個のスタックの代わりに、さらに単純なデータ構造が必要です。
説明と例:
このアルゴリズムのステップ 1 は、サブシーケンスとして任意の 1 桁の数字を含む最短のサフィックスを決定します。次に、このサフィックスに隣接し、1 桁の数字も含む最短の部分文字列を見つけます。これらを組み合わせると、任意の 2 桁の数字を含む最短の接尾辞が得られます。このプロセスは、3 桁、4 桁のサフィックスなどについても続けられます。また、この前処理ステップでは、これらの n 桁の数字の左側にどの数字を書き込むことができるかを判断し、対応するサブシーケンスが入力文字列のサフィックスに存在するようにします。 (この情報はビットセットに含まれています)。
たとえば、入力文字列の場合、12345678901
このステップでは、インデックス「1」で始まる接尾辞に 1 桁の数字が含まれている可能性があると判断されます。また、次の方法でビットセットを埋めます。
index: bitset:
10 0000000010
9 0000000011
8 1000000011
7 1100000011
6 1110000011
5 1111000011
4 1111100011
3 1111110011
2 1111111011
1 0000000000
0 0000000010
ステップ 2 と 3 では、いくつかのまれなケースを扱います。
ステップ 4 は、位置 "0" のビットセットを調べて、最小の開始桁を見つけることから始まります。この例では、ビット "1" が設定されています。これは、2 桁の数字を "1" で始めることができないことを意味します (そのような数字はすべて文字列に含まれています)。また、「0」から始めることはできません。次の unset ビットは「2」なので、番号を「2」から始めます。
対応するスタックを使用するか、文字列を順番に検索して、最初の数字「2」の位置に到達することができます。数字の残りの桁は、数字「2」の後に始まる接尾辞にある必要があります。このサフィックスの開始位置のビットセットは「1111111011」です。これは、このサフィックスで唯一の未使用の数字が「2」であることを意味します。「counter+1」は 2 で、ステップ 4 の反復を 2 回使用したので、ここで終了します。したがって、答えは「22」です。
これは、時間の複雑さが劣る他のアルゴリズムO(answer + length of the string)
です。
数字 (0 から 9) ごとに、インデックスの配列を準備します。各インデックスは、指定された位置または右側にある最も近い数字の出現を指します。例えば:
For string 216989210...
and digit "1": 11777777...
これは、入力配列を逆方向にスキャンすることで実装できます。適切な数字が表示されるとすぐに、そのインデックスをインデックス配列に書き込み始めます。上記の例では、これは、位置 7 で右端の数字 "1" を確認し、インデックス 1 で数字 "1" の別の発生が確認されるまで、インデックス配列を 7 で埋めることを意味します。次に、残りの位置をこのインデックスで埋めます。
O(answer * length of the string)
これで、OP に記載されているアルゴリズムの複雑さを からに簡単に減らすことができますO(answer + length of the string)
。現在の数値の次の桁の最も近い位置を取得するには、インデックス配列の 1 つによって提供されるリンクをたどるだけです。
たとえば、最初の 61 個の非負の数を試してから、数 "61" について、最初の位置で "6" のインデックス配列を調べて、インデックス "2" を見つけることができます (このインデックスは既に見つかっているため、これは実際には必要ありません)。 "60" を処理している間)、次の位置 (2+1) で "1" のインデックス配列を調べて、インデックス "7" を見つけます。つまり、指定された文字列に「61」があり、「62」を続けることができます...