タイトル説明
いくつかの要素の配列の先頭には、配列、我々は回転呼んで配列の最後に移動しました。アレイ出力の非回転、回転のソートされた入力配列保存最小要素。例えば、配列{3,4,5,1,2}、{1,2,3,4,5}は最小のアレイの回転です。注:配列のサイズは0、リターン0である場合は、すべての要素は、0より大きいに記載されています。
アイデア解析
使用した二分探索であるように、アイデアをアレイの回転が二つに分けることができるサブソートされた配列、および最小要素これら2つの配列の境界配列は、中間要素を決定すると、その要素に2つの索引ポインタのポインティングを終了するには、配置された端サイズ関係:
- 場合中間要素 > =最初の要素は、中間要素の最小の要素、最初のポインタを探して、後述する中間要素。
- 中間要素が<=最後の要素、中間要素、第二のポインタの前に見て最小の素子中間要素。
- これは、前述のサブアレイの最後の要素に、最終的な第一のポインタポイントを狭い検索を繰り返し、第2のポインタは、最小要素であるバックの部分配列の最初の要素、すなわち、隣接する二つのポインタをポイントしますそれはポインタの2番目の要素であります
特別な場合は、中間要素、最初の要素へのポインタ場合、第2の要素ポインタポイントが等しい場合、アイデアは、二つの点を使用することができる見つけるために使用することができないの順序を見つけるために最小値を見つけるためのアイデアを
Javaコード
public class Offer011 {
public static void main(String[] args) {
// int [] arr = {3,4,5,1,2};
int [] arr = {1,0,1,1,1};
int minNumberInRotateArray = minNumberInRotateArray(arr);
System.out.println(minNumberInRotateArray);
}
public static int minNumberInRotateArray(int [] array) {
return Solution1(array);
}
/**
* 利用二分查找的思路,注意:要考虑特殊情况
* @param array
* @return
*/
public static int Solution1(int [] array) {
int index1 = 0;
int index2 = array.length-1;
int indexMid = index1;
while(array[index1]>=array[index2]) {
if(index2-index1==1) {
indexMid= index2;
break;
}
indexMid = (index1+index2) >>1;
if(array[index1] == array[index2] && array[indexMid] == array[index1]) {
//特殊情况:要用顺序查找
return MinInOrder(array, index1, index2);
}
if(array[indexMid]>=array[index1]) {
index1 = indexMid;
}else if(array[indexMid]<=array[index2]) {
index2 = indexMid;
}
}
return array[indexMid];
}
/**
* 在index1和index2之间顺序查找最小值
* @param array 在此数组中进行查找
* @param index1 开始索引位置
* @param index2 结束索引位置
* @return
*/
private static int MinInOrder(int[] array,int index1,int index2) {
int min = array[index1];
for(int i=index1+1;i<=index2;i++) {
if(min > array[i]) {
min = array[i];
}
}
return min;
}
}