2013-01-07 18 views
13

は私がある問題を考えましたと範囲[s、e]、つまりsとeが与えられ、その配列の範囲内で最も近いmの数を見つけなければなりません(A [s] -A [e])。検索最も近い数が

インデックスの配列は1からnまでとすることができます。例えば

:私ができる

n<=10^5 
t<=n 

すべての思考は、すべてのテストケースのためのO(n)の溶液である:

A = {5, 12, 9, 18, 19} 
    m = 13 
    s = 4 and e = 5 

だから答えは18

制約でなければなりません私はよりよい解決策が存在すると思います。

+2

もしどのような方法でもソートされなければ、A [s]とA [e]間のすべての値にアクセスしなければならないので、O(n)です。またはむしろO(e-s)、私は思います。 – femtoRgon

+0

@femtoRgon私はそれを知っているが、あらゆるデータ構造を使用することで、可能だと思う。 –

+0

最大サイズ制限(10^5)を指定しているので、複雑さO(1)ではない - つまり一定の時間ですか? – Chris

答えて

9

これは概略のスケッチです: データからsegment treeを作成します。各ノードでは、左右のインデックスなどの通常のデータのほかに、ソート順に格納された、そのノードをルートとするサブツリーにある番号も格納します。これは、セグメントツリーをボトムアップ順に構築するときに実現できます。リーフのすぐ上のノードでは、2つのリーフ値をソート順に格納します。中間ノードでは、標準のマージを使用して結合できる左の子と右の子に数値を保持します。ツリーにはO(n)個のノードがあり、このデータを保持することは全体的なO(nlog(n))を取るべきです。

このツリーがあると、すべてのクエリに対して、指定された範囲([s、e])内の適切なノードに到達するまでパスを歩きます。チュートリアルが示すように、1つまたは複数の異なるノードが結合して指定された範囲を形成します。木の深さがO(log(n))であるので、これはこれらのノードに到達するクエリあたりの時間です。各クエリはO(log(n))でなければなりません。範囲内に完全にあるすべてのノードについて、それらのノードに格納されているソートされた配列内でバイナリ検索を使用して最も近い番号を見つけます。再び、O(log(n))。これらの中で最も近いものを見つけ、それが答えです。したがって、O(log(n))時間内に各クエリに答えることができます。

私がリンクするチュートリアルには、実装が簡単なスパーステーブルなどの他のデータ構造が含まれており、クエリごとにO(sqrt(n))を与える必要があります。しかし、私はこれについてはあまり考えなかった。

+0

どのノードをツリーに入れるかはどのように決めるのですか?すべての可能な左右のインデックスを追加することはできません。 – Chris

+0

セグメントツリーは配列の上に構築され(各配列要素は葉です)、2つの葉ノードはすべて1つずつ結合されて次のレベルのノードになります。チュートリアルで示されているように、配列全体にツリー全体を構築します。次に、任意の範囲内の集約データを検索するには、ツリー内の2つのブランチを一番下にトラバースする必要があります。 – mayank

+0

さて、今すぐ入手してください。私は悪いです - 私はセグメントツリーで作業しましたが、どういうわけか彼らがこの問題にどのように適合しているか想像できませんでした。 – Chris

-1

私はかなり速い解決策が存在しないと確信しています。

配列Aはありませんが、各テストケースには並べ替えられない番号の配列が含まれています。 (Aからsまでの配列スライス)。

この場合、各テストケースの線形検索よりも明らかに優れた方法はありません。

元の問題はどのように上記のバリエーションよりも具体的ですか?追加された唯一の情報は、すべてのスライスが同じ配列から来ていることです。私は、この追加の制約がアルゴリズムの高速化に使用できるとは思わない。

EDIT:私は訂正しました。セグメントツリーのデータ構造は機能するはずです。

+2

これはわずかな違いではなく、大きな違いです。 'A'をあらかじめ持っていると、前処理中に検索を高速化できるデータ構造を作成することができます。 – interjay

+0

私の主張は、そのようなデータ構造が存在しないということでしたが、別の答えの中のセグメントツリーのアイデアは私にそうではないと確信しました。 – Chris

-1

アレイをソートしてバイナリ検索します。複雑さ:o(nlogn + logn * t)

+1

は機能しません。クエリの一部として元の配列にインデックスがあります。ステートメントをもう一度読んでください。 –

関連する問題