#Find Low or High Index
##説明
整数型のソートされた配列と、指定された要素(key)が位置する最も低いインデックス(low index)と高いインデックス(high index)を返す。もし、指定された要素がその配列にない場合は-1を返します。配列の長さは数百万単位で、多くの重複要素を許します。
##例
次の例では、low index と high index は次のようになります。
key:1 low = 0 および high = 0
key:2 low = 1 および high = 1
key:5 low = 2 および high = 9
##ヒント
Binary Search
##解説
###Runtime Complexity
Binary Search を使用しているため、実行時間はO(logn)です。
###Memory Complexity
定数のO(1)です。 追加のメモリは使用ましせん。 ただし、Binary Search が再帰的に実装された場合、
関数呼び出しによるスタックで暗黙的にO(logn)、メモリが使用されることに注意してください。
ただし、ここでは反復(Iteration)に焦点を当てます。
###思考
配列サイズは数百万単位であるため、ソートされた配列をlow indexおよび high indexでO(n)で
線形スキャンすることは非常に非効率的です。 代わりに、少し修正を加えてBinary Searchを使用して、
特定のkey の low indexと high index を見つけます。
low index を見つけるためのアルゴリズムを見てみましょう。
- すべてのステップで、low index と high index の間の配列を検討します。また、low index と high index の中間の mid index を計算します。
- mid の要素が key 以上の場合は、high = mid - 1になります。もし、mid の要素が keyと同じの場合でも、そのindexが最低のindexとは限らないことに注意します。
*high index を見つける場合も上記のプロセスとほぼ同じです。以下に実装コードがあります。
##実装
import java.util.List;
public class findLowHigh{
public int binary_search(List<Integer> arr, int low, int high, int key, boolean search_low){
while(low <= high) {
int mid = low + (high - low) / 2;
if (search_low) {
if (arr.get(mid) >= key) { // Search the left half for the next
high = mid - 1;
}
else { // Search the right half for the next
low = mid + 1;
}
}
else {
if (arr.get(mid) <= key) { // Search the left half for the next
low = mid + 1;
}
else { // Search the right half for the next
high = mid - 1;
}
}
}
if (search_low) {
if (low == - 1) {
return low;
}
else if (low < arr.size() && arr.get(low) == key) {
return low;
}
} else {
if (high == -1) {
return high;
}
else if (high < arr.size() && arr.get(high) == key) {
return high;
}
}
return -1;
}
public int find_low_index(List<Integer> arr, int key) {
return binary_search(arr, 0, arr.size() - 1, key, true);
}
public int find_high_index(List<Integer> arr, int key) {
return binary_search(arr, 0, arr.size() - 1, key, false);
}
}
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
findLowHigh algorithm = new findLowHigh();
List<Integer> array = Arrays.asList(1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,5,5,5,6,6,6,6,6,6);
int key = 5;
int low = algorithm.find_low_index(array, key);
int high = algorithm.find_high_index(array, key);
System.out.println("LowIndex of " + key + " : "+low);
System.out.println("HighIndex of " + key + " : "+high);
key = -2;
low = algorithm.find_low_index(array, key);
high = algorithm.find_high_index(array, key);
System.out.println("LowIndex of " + key + " : "+low);
System.out.println("HighIndex of " + key + " : "+high);
}
}