[質問要件] n番号とnを与えます。これで、O(1)内のO(n)空間で50%以上の回数が発生する数を見つける必要があります。
[でたらめを開始]最初に、私はこの質問が即座に盲目にされている(tot)/~~~(。*)を見ました。 O(n)の時間要件のみがある場合、ハッシュ(つまり、時間の空間で)で即座に解くことができ、O(1)の空間を解くことは難しいと思われます。
[思考1]ダブルループ、これはこの問題を解決するための最も効率的ではない方法です。つまり、各数値に表示される回数を計算し、時間の複雑さo(n^2)が直接出ています。
[Thought 2]最初に並べ替え、類似の数値を一緒に配置し、最初の数値からトラバースします。次の例を挙げてください:1000012、sort:0000112、0から開始、カウンターt = 0を設定します。40秒があり、t = 4があり、その半分以上が出力0であることがわかります。
[Thought 3]それは、時間のために空間を交換し、1次元配列を作成するためにハッシュするという考え方に2つの意味があります。たとえば、a [x] = yは、数xがy回表示されることを表します。この方法の時間の複雑さはo(n)ですが、スペースは本当に...私はそれについて話しません(*  ̄ ̄)
[思考4]最初に確率を計算し、要件を満たす可能性が最も高いこれらの数値の数を選択し、次にいくつかをランダムに選択します。これ...それを忘れてください。
[思考5]今日のトピックは、いわゆるMJRTYアルゴリズムであり、大多数の投票アルゴリズムとしても知られています。主なアイデアは次のとおりです。(このアルゴリズムの時間の複雑さはo(n)です!スペースに追加のストレージは必要ありません。したがって、スペースの複雑さはo(1)!!!)
count == 0の場合、配列の現在の要素に投票値を設定し、カウントを1に割り当てます。
それ以外の場合、投票および現在アレイ要素が同じ値、++、そうでない場合はカウントされている場合。
アレイがスキャンされるまで、上記の2つのステップを繰り返します。
カウントは0に割り当てられ、最初からアレイを再度スキャンします。配列要素の値が投票値と同じ場合、配列がスキャンされるまで++をカウントします。
現時点でカウントの値がn/2以上の場合、投票の値が返されます。そうしないと-1が返されます。
以下はコードの実装です。質問は結果が存在する必要があることを保証するため、チェックと検証の最後のステップを省略しました。
重要なコードは次のとおりです。
#include <iostream> namespace std; int lenを使用しています。 void find(int* a、int n){char候補; int ntimes、i; for(i = ntimes = 0; i <n; i ++){if(ntimes == 0)候補= a [i]、ntimes = 1; else {if(condation == a [i])ntimes ++; els ntimes-;} } int main(){cin >> len; int a [len];上記は、編集者によって導入された発生数の半分以上(50%)の数です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!