タイトル:デジタルアレイは、アレイの半分以上の長さを出現回数は、この番号を見つけます。例えば、入力アレイ9の長さは{1,2,3,2,2,2,5,4,2}。番号2は、配列内の5回、アレイの半分以上の長さ、出力2が表示されているので。
最も簡単な解決策は、我々は簡単回発生し、各番号の数をカウントすることができ、配列をソートすることです。時間の複雑さをソートすると、O(nlogn)であるため、アルゴリズムの時間計算量はO(nlogn)ことはありませんインタビュアーの満足度です。
溶液:O(N)アルゴリズムパーティション関数:
我々は、トピック自体慎重な分析に戻る場合は、以前のアイデアを見つけるでしょう、アカウントに、配列の特性を取ることはありませんでした:配列は、回数を持っている数は、配列の半分以上の長さを表示されます。このアレイがソートされた後、アレイの中央に並べ替えた場合、デジタル周波数の特定の数は、より配列の長さの半分よりも表示されること統計中央値、すなわち、長さの配列N、最初のN / 2が多数あります。私たちは、任意の多数のK-配列を取得するために、成熟したO(n)のアルゴリズムを持っています。
当社のアルゴリズムは、インスピレーションを得たクイックソートアルゴリズムの対象となります。ランダムクイックソートアルゴリズムでは、まず、ランダムに配列内の番号を選択し、選択多数番号がでランク付けされるよりも比は、その左の数字番号の行を選択するように番号の配列順序を調整しますそれはそうです。例えば、選択されたインデックス番号は、この番号は、配列の中央値正確にn / 2です。N / 2よりもそのインデックス大きいが、その後、中央値は、その左側に位置しなければならないなら、私たちは、左側のセクション上にアレイ状にそれを見つけることができます。N / 2未満のインデックス場合、中央値は、その後、我々はそれの右の右の部分でそれを見ることができなければなりません。これは典型的な再帰的なプロセスです。
//适用partition函数
public int partition(int[] arr,int left,int right){
int result = arr[left];
if(left > right)
return -1;
while(left <right){
while(left <right && arr[right]>= result){
right --;
}
arr[left] = arr[right];
while(left <right && arr[left] <result){
left++;
}
arr[right] = arr[left];
}
arr[left] = result;
return left;
}
public int moreThanHalfNum(int[] arr){
if(arr.length ==0)
return -1;
int length = arr.length;
int middle = length >>1;
int start = 0;
int end = length -1;
int index = partition(arr,start,end);
while(index != middle){
if(index >middle){
end = index - 1;
index = partition(arr,start,end);
}
else{
start = index + 1;
index = partition(arr,start,end);
}
}
int result = arr[middle];
if(!checkMoreThanHalf(arr,result)){
result = -1;
}
return result;
}
//验证是否存在
public boolean checkMoreThanHalf(int[] arr,int number){
int times = 0;
for(int i = 0;i<arr.length;i++){
if(arr[i] == number)
times ++;
}
boolean isMoreThanHalf = true;
if(times *2 <= arr.length){
isMoreThanHalf = false;
}
return isMoreThanHalf;
}
溶液2:アレイの特性に応じてO(N)アルゴリズムを識別する。
次は別の角度からこの問題を解決するために来ます。回数は、それが他のすべての数字よりも外観が表示され、さらに言うことです配列の半分以上の長さを表示される配列番号の数があります。だから我々は、2つの値の配列を、時間を節約することができます:1は、数値配列、回数です。私たちは次の桁までの時間を通過し、として私たちは、同じ回数プラス1の番号の前に次の桁の番号を保存する場合は、数が0の場合と異なる図面内の次の数は、我々が以前に保存した場合、その後、1ずつデクリメント、我々次の番号を維持する必要性、および回数は、私たちがデジタル周波数が1に設定されている最後の時間を見つけるようにしてください、さらに表示されますが、他のすべての数字よりも表示されることの数を探しているので、番号が1に設定されています対応する番号。
public int moreThanHalfNum2(int[] arr){
if(arr.length == 0)
return -1;
int result = arr[0];
int times = 1;
for(int i = 1;i<arr.length;i++){
if(times == 0){
result = arr[i];
times = 1;
}else if(arr[i] == result)
times++;
else
times--;
}
if(!checkMoreThanHalf(arr,result))
result = -1;
return result;
}