NUMSの配列の長さですべての数字nは0〜N- 1 の範囲。一部のデジタル配列が重複しているが、各回数が数回繰り返したかわからない、繰り返し何の数字かわかりません。重複した数字のいずれかの配列を見つけてください。 [実施例1 ] 入力: [ 2、3、1、0、2、5、3 ] 出力:2または3 の制限の] 2 <= N - <= 100000
[問題解決のアイデア]
:考え、最初のソート列、および重複した数字を見つけることトラバース。
C ++に内蔵されたソート機能を使用してソートされた、この方法は、時間複雑性O(nlogn)であり、空間的複雑さはO(1)です。
クラス解決{ パブリック: INT findRepeatNumber(ベクトル< INT >&NUMS){ ソート(nums.begin()、nums.end())。 以下のために(INT iが= 0 ; I <nums.size() - 1 ; I ++ ){ 場合(NUMS [I] == NUMS [I + 1 ]) 戻りNUMS [I]。 } リターン - 1 。 } }。
思考2:ハッシュテーブルを使用しました。最初から配列によって、要素がハッシュテーブルにない場合は、テーブルに新しいキーと値のペアを追加し、ハッシュテーブル内の要素ならば、その要素を返します。方法、時間計算量はO(N)であり、空間的な複雑さはO(N)です。
クラス解決{ パブリック: INT findRepeatNumber(ベクトル< INT >&NUMS){ unordered_map < INT、INT > BP。 以下のために(INT iが= 0 ; I <nums.size(); I ++ ){ 場合(bp.find(NUMS [I])== bp.end()) bp.insert({NUMS [i]は、1 }) ; それ以外の 戻りNUMS [i]は、 } リターン - 1 。 } }。
3思考: O(n)との時間の複雑さは、スペースの複雑さは、それのためにO(1)アルゴリズムでありますか?
私たちは、デジタルアレイが中のn-1に0であることに注意してください。配列が重複した数字をしない場合は、次の配列のソート番号の後にI Iマークされた場所が表示されますまで。アレイが重複番号を持っているのでしかし、そこにデジタル位置の複数の一部であってもよく、これらの位置のいくつかはデジタルではないかもしれません。
それでは、まだ各番号に一度最初から最後まで、アレイをスキャンし、配列を並べ替えてみましょう。(Mで示される)は、デジタル第1の比較図の添字iをスキャンでないときIに等しいです。もしそうならば、次の番号をスキャンします。そうでない場合、それはm個の数字を比較してみましょう。
そして、それは反復数(この数はIであり、mが出現したインデックス位置にある)を見つけるために、m番目の桁に等しい場合。それはデジタルであり、mが等しくない場合、それに属するm個の位置にi番目及びm番目の桁デジタルスイッチングを置きます。私たちは、重複番号を見つけるまで、その後、この比較、交換プロセスを再読み込み。
配列{2,3,1,0,2,5,3}の例では、デジタル検索重複ステップを分析します。(ゼロから数えて、一貫した配列インデックス)数字0の配列が2であり、そしてそれへのインデックスが等しくない場合、それは数2及び添字1交換です。アレイを切り替えた後} {1.3.2.0.2.5.3あります。このとき、最初の桁が0である、それはまだインデックスに等しくないが、それは、配列{3,1,2,0,2,5,3}を得るために、数1のように交換機3を下降し続ける。ピック配列{0,1,2,3,2,5,3}を得るために、デジタル0および3 0 3桁の交換をダウン続けます。このとき、0のデジタル値は、次の数値をスキャンする、0です。次のいくつかの数字、下付き数字1、2の上に、3が2、1だった、とその値は、添え字が同じであるが、何もする必要はありません。その値とそのインデックス番号2によりとしてスキャン4次は、デジタル及び添字2と比較し、等しくありません。この時点で、配列の添字2に注目するので、重複番号を見つける番号2、すなわち下部の図2と浮上している4標識二つの位置で標識されています。
クラスのソリューション{ パブリック: int型 findRepeatNumber(ベクトル< int型 >&NUMS){ のためには、(int型は、私は= 0 ; I <nums.size(); I ++ ){ しばらく(!NUMS [I] = I){ 場合(NUMS [I ] == NUMS [NUMS [I]) 戻りNUMS [I]。 他の スワップ(NUMS [I]、NUMS [NUMS [I])。 } } リターン - 1 。 } }。