ソートされた文字列の辞書式順序で文字列のリストをソートする


8

LETアルファベット上の文字列の集合で合計に含まれていることをのシンボル。A{0,,m1}n

あなたの仕事は、各文字列を内部的にソートし、結果の文字列を辞書式順序でソートすることです。(アルゴリズムはこのように動作する必要はありません。)

例:

入力:33123 15 1 0 54215 21 12

出力:0 1 12 12 12333 12455 15

時間と空間でそれを行う方法を見つけました。O(m+n)O(mn)

サイズ配列を作成し、すべてのセルに初期値を与えるような配列を使用しているため、スペースは時間よりも大きくなっています。nO(1)

各文字列(時間とスペース)をソートするためにバケットソートを使用し、コレクション自体(時間とスペース)をソートするためにワードツリーを使用しました。しかし、私の解決策は複雑すぎます。O(m+n)AO(m+n)O(mn)

時間とより少ないスペース、またはより速い、より良いソリューションがありますか?O(m+n)O(m+n)

ソリューションは確定的でなければならず、ハッシュマップやその他の統計アルゴリズムは使用できません。


私の解決策:スマート配列は、サイズ配列であり、で作成および「初期化」できます。mO(1)

それらのいずれも初期化せずにのサイズの3つの配列を作成し、という単一の整数変数も保持します。mC

最初の配列にはデータが含まれています。2番目の配列には、3番目の配列のセルへのポインターが含まれています。3番目の配列には、2番目の配列のセルへのポインターが含まれています。は、これまでに初期化されたセルの数が含まれます。C

セルの値を設定したいとします(このセルで初めて行う場合を想定)。次に、最初の配列のセルに移動して、目的の値に設定します。ii

次に、2番目の配列のセルに移動し、3番目の配列のセルを指すように設定します。3番目の配列のセルを、2番目の配列のセルを指すように設定します。を1 増やします。iCCiC

セルがゴミ箱であるかどうかを知りたいとします(つまり、まだ何も設定していないことを意味します)。j

2番目の配列のセルし、(3番目の配列の)セル(2番目の配列)が指すセル番号を確認します。これをと呼びます。jjk

場合、はゴミ箱です(これまでに初期化されたセルしかなく、はそれらの1つではないため)。k>CjCj

場合、(3番目の配列の)指すセルを調べます。でない場合、はゴミです。そうでなければはゴミではありませんk<Ckjjj

これにより、このセルを初期化したかどうか、および初期化していないかどうかを各ステップで知ることができます。したがって、時間でサイズ配列を作成して「初期化」しました。mO(1)

主なトリックは、最初に配列全体を初期化することではなく、これまでに初期化したセルを知る方法を見つけ、「見た」ときにのみセルを初期化することです。RAMモデルでは、初期化せずに任意のサイズの配列を作成するのに時間かかります。O(1)


次数mの単語ツリーは、TRIEを一般化したものです。各ノードには、その息子へのポインタの配列が含まれています。配列サイズはです。各ノードには、このノードによって記述されているセットの数を示すカウンターも含まれています。m

単語(セット)を追加するたびにスマート配列を使用しているので、時間とスペースしかかかりません。AO(|A|)O(m|A|)


5
時間はスペースより小さくすることはできません。あなたは何らかの方法で浮気をしています。
Yuval Filmus

もちろんできます。リセットせずにサイズnの配列を作成するには、O(1)が必要です。cとc ++についても同様です。次に、非常に単純なデータ構造を使用して、使用したセルと不要なセルを追跡できます
Ofer Magen

3
CとC ++はあまり気にしません。通常、RAMマシンモデルでアルゴリズムを分析します。このモデルでは、時間はスペースよりも小さくすることはできません。スマート配列がアクセスごとにで実際に機能しないことを少し心配しています。O(1)
Yuval Filmus

1
RAMモデルは、サイズnの配列を定義するためにO(1)を使用します(コンピューターは、開始ポインターと終了ポインターを定義するだけで済みます)。ゼロにリセットするにはO(n)が必要です。C ++はramモデル言語なので、この例を持っています
Ofer Magen

@YuvalFilmus Time cannot be smaller than space本当。You are cheating in some way「時間と空間」からは従いません:、 -空間の境界は不必要に緩く見えます。O(m+n)O(mn)1mnxm+yn+zO(mn)
greybeard 2018年

回答:


0

時間と空間でこれを解決することもでき。O(nlogn)O(n)

  • まず、mergesortを使用して各単語を並べ替えます。この実行時間は最大でであり、スペースの使用量はです。O(nlogn)O(n)

  • 次に、すべての単語を単語トライに格納します。単語trieを適切に実装すると、この時間と空間はになります。特に、トライの各ノードでは、子のセットを(配列としてではなく)ハッシュテーブルとして保存する必要があります。このようにして、ノードでのストレージは、ノードが持つ子の数に比例し、子を見つけるためのルックアップは時間で実行できます。したがって、このステージの実行時間は時間と空間です。O(n)O(1)O(n)O(n)

  • 最後に、トライからすべての単語を読み上げます。これには、各ハッシュテーブルを取得し、その内容をソートすることが含まれます。これらの並べ替え手順はすべて、最大で時間かかります。O(nlogn)

結果のデータ構造は非常に単純に見えます。ハッシュマップのサポートが組み込まれている言語(JavaScript、Pythonなど)で実装する場合は、特に簡単です。

または、ハッシュマップをバランスのとれたバイナリツリーデータ構造に置き換えて、同様の実行時間を得ることができます。


「スマートアレイ」に関する一般的な注意事項:

「スマート配列」の使用をハッシュテーブルに置き換えることができます。そうすることで、(予想)時間の読み取りと書き込みを実行する機能を維持できます。特に、を設定代わりに、値をキー格納します(つまり、マッピングをハッシュテーブルに追加します)。値を読み取りたい場合は、代わりにハッシュテーブルでを検索し、そこにあるものをすべて返します。このようにして、スペース使用量は「スマートアレイ」の初期化されたエントリの数に比例し、各アクセスには(予想)時間かかります。O(1)A[i]:=vvkkvA[i]iO(1)


ハッシュテーブルは統計ツールであり、確定的なソリューションが必要です。マージソートの使用は必要ありません。1からmの範囲の整数であるためバケットソートを使用でき、O(n + m)で解く
Ofer Magen

ただし、スマートアレイは完全に確定的です
Ofer Magen '19

4
あなたはより速く要求しました O(n+m)O(nlogn) より速い O(n+m)一部のパラメーターについて-ただし、他のパラメーターについてはそうではありません。ハッシュテーブルを使用したくない場合は、回答で提案したように、バランスのとれたバイナリツリーデータ構造を使用します。O(nlogn) 実行時間と O(n)スペースの境界、そして完全に決定論的にそうします。
DW

@OferMagenコレクションAが事前にわかっている場合は、最小限の完全ハッシュを使用できるため、衝突は発生しません。
Gerardo Zinno

0

セットを並べ替えることができます S 整数アルファベット上の文字列の {0,1,,σ1} サイズの σトライを使用してO(dσ) 時間と空間、どこ d区別する接頭辞ですS

ハッシュテーブルを使用しないソリューションを次に示します。

しましょう ds 文字列の最短の接頭辞の長さ sS それを他の文字列と区別します S。の識別接頭辞S と定義されている d=sSds

問題を解決するアルゴリズムは、分割統治アプローチを使用します。これは、最上位の桁(char)から始まるRadixSortです。

1)作成 σ バケツ 0,1,,σ1

2)文字列を最初から1文字ずつ処理し、それらを σ CountingSortを使用するバケット O(1) 時間。

3)複数の要素を含むバケットに対して、次の文字を使用してプロセスを繰り返し、それらをソートします。

4)グループを左から右に連結して、順序付けられたシーケンスを取得します。

このアルゴリズムは、 σ-aryトライ。すべてのノードが σ サイズの配列と文字列は葉に格納されます。

ここに例があります。

しましょう σ なる 5 そして S={410,013,042,111,001,444}

以下は、アルゴリズムによって生成されたトライです。 トライ

各ストリング s サイズのパスを綴る O(ds) ノードが指す前 s創造された。それらのパスの各ノードはO(σ) スペースと O(σ) 割り当てられる時間。


このアプローチを使用しますが、 σノードから出てくるエッジに比例したサイズのハッシュテーブルを持つサイズのノード。アルゴリズムを実行できます。 O(d logσ) 平均時間と O(d)スペース。
Gerardo Zinno
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.