[Sword Finger Offer Second Edition] [インタビューの質問3:配列内の繰り返し数]

タイトル:長さnの配列のすべての数値は0からn-1の範囲です。配列内のいくつかの数値が繰り返されていますが、何回繰り返されているのか、また各数値が何回繰り返されているのかわかりません。配列内で重複する番号を見つけてください。


例示的な
  例では、入力アレイ7 {2,3,1,0,2,5,3}の長さがあれば、対応する出力は繰り返し数2又は3です。
  問題分析
この問題を解決する簡単な方法は、最初に入力配列をソートすることです。並べ替えられた配列で重複する番号を見つけるのは簡単です。並べ替えられた配列を最初から最後までスキャンするだけです。長さnの配列のソートには、O(nlogn)時間かかります。
  この問題を解決するには、ハッシュテーブルを使用することもできます。配列の各番号を最初から最後までスキャンします。番号をスキャンするときに、O(1)時間を使用して、その番号がハッシュテーブルに既に含まれているかどうかを判断できます。番号がハッシュテーブルに存在しない場合は、ハッシュテーブルに追加します。番号がハッシュテーブルに既に存在する場合、重複する番号が見つかります。このアルゴリズムの時間の複雑さはO(n)ですが、サイズO(n)のハッシュテーブルを犠牲にして時間効率を向上させます。空間複雑度O(1)のアルゴリズムがあるかどうかを見てみましょう。
  配列の数値はすべて0からn-1であることがわかりました。この配列に重複する数値がない場合、配列がソートされた後、添え字iの位置に数値iが表示されます。配列には数値が繰り返されるため、位置によっては複数の数値があり、位置によっては数値がない場合があります。
次に、この配列を並べ替えて、この配列のすべての番号を最初から最後までスキャンします。添え字がiの数値をスキャンする場合、最初にこの数値(mで示される)がiに等しいかどうかを比較します。はいの場合は、次の番号をスキャンします。そうでない場合は、m番目の数と比較します。
  それがm番目の数値と等しい場合、重複する数値が検出されます(数値は添え字iとmの両方に表示されます)。m番目の数と等しくない場合は、i番目の数をm番目の数と交換し、mをその位置に置きます。次に、重複する番号が見つかるまで、比較と交換のプロセスを再度読みます。
  配列{2,3,1,0,2,5,3}を例として、重複する番号を見つける手順を分析します。配列の0番目の数(0から数え、配列の添え字と一致)は2であり、その添え字と同じではないので、添え字2を持つ1と交換します。交換後の配列は{1.3.2.0.2.5.3}です。この時点で、0番目の数値は1であり、それでもその添え字と等しくありません。配列3、1、2、0、2、5、3}を取得するために、添え字1を持つ数値3と引き続き交換します。次に、0桁目3と3桁目0を交換して、配列{0,1,2,3,2,5,3}を取得します。このとき、0桁目の値は0であり、次の桁がスキャンされます。次の数のうち、添え字が1、2、3の3つの数字はそれぞれ1、2、3であり、それらの添え字と値は等しいため、アクションは不要です。次に、下付き文字4の数値をスキャンします。その値は下付き文字と等しくないため、下付き文字2の数値と比較します。このとき、配列内の添え字が2の数字も2であることに注意してください。つまり、数字は添え字2と添え字4の2つの位置に表示されるため、重複した数字が見つかります。

1  パブリック クラスTest3 {
 2      public  static  int duplicate(int [] numbers){
 3          if(numbers == null || numbers.length <1 ){
 4              return -1 ;
5          }
 6  
7          forint i:numbers){
 8              if(i <0 || i> = numbers.length){
 9                  return -1 ;
10              }
 11          }
 12  
13          forinti = 0; i <numbers.length; i ++ ){
 14              // 数値[i]がiと同じでない場合は、常に
15              交換します(numbers [i]!= i){
 16                  // i位置の数値と数値[i]の位置は同じで、重複した数値
17                  があることを示しますif(数値[i] == 数値[数値[i]]){
 18                      戻り数値[i];
 19                  } そうでなければ{
 20                      スワップ(数値、i、数値[ i]);
 21                  }
 22              }
 23          }
 24          return -1 ;
 25      }
 26  
27      private static  void swap(int [] data、int x、int y){
 28          int tmp = data [x];
29          data [x] = data [y];
30          data [y] = tmp;
31      }
 32  
33      public  static  void main(String [] args){
 34          int [] numbers = {2,3,1,0,2,5,3 };
35          System.out.println(duplicate(numbers));
36      }
 37 }

 運用実績

 

参考ブログ:https : //blog.csdn.net/derrantcm/article/details/46811855

 

おすすめ

転載: www.cnblogs.com/lkylin/p/12750487.html