全脳:
私は(10'000と1'400'000間のサイズの)整数の大きな配列を持っています。私は、値に大きな最初の整数を取得したいです。値は、配列内になることはありません。
私は、さまざまなソリューションを見てきたが、私は発見しました。
- 各値を推定し、(O(n)の時間計算量で)ソートされたリストまたは配列のために設計されていない方法。
- (O(n)の以上の時間複雑で、しかし他の言語で、私はよく分からないので)、再帰的および/または非常に大きなリストや配列のために設計されていないメソッド。
私は自分の方法を設計しました。ここにあります :
int findClosestBiggerInt(int value, int[] sortedArray) {
if( sortedArray[0]>value ||
value>sortedArray[sortedArray.length-1] ) // for my application's convenience only. It could also return the last.
return sortedArray[0];
int exp = (int) (Math.log(sortedArray.length)/Math.log(2)),
index = (int) Math.pow(2,exp);
boolean dir; // true = ascend, false = descend.
while(exp>=0){
dir = sortedArray[Math.min(index, sortedArray.length-1)]<value;
exp--;
index = (int)( index+ (dir ? 1 : -1 )*Math.pow(2,exp) );
}
int answer = sortedArray[index];
return answer > value ? answer : sortedArray[index+1];
}
それはO(ログn)の時間複雑性を有します。長1'400'000のアレイと、それは一方のブロック内のループ21回になります。それでも、私はそれを向上させることができないことをわかりません。
それを行うには、より効果的な方法は、外部パッケージの助けを借りずに、ありますか?この計算はかなり頻繁に発生するため、保存された任意の時間は素晴らしいです。
ありがとう!
ruakh:
ジーンの答えが示すように、あなたはバイナリ検索でこれを行うことができます。ビルトインjava.util.Arrays
クラスが提供するメソッドあなたのためにそれを行うには:binarySearch
int findClosestBiggerInt(final int value, final int[] sortedArray) {
final int index = Arrays.binarySearch(sortedArray, value + 1);
if (index >= 0) {
return sortedArray[index];
} else {
return sortedArray[-(index + 1)];
}
}
あなたはより速く、あなたが書いた方法よりもはるかにすることを見つけることができます。それはまだだO(ログnは)時間が、それはのような高価な操作を実行していないため、一定の要因は、はるかに低くなりますMath.log
とMath.pow
。