回転配列で最小値を検索-java


回転配列で最小値を検索(java)
これも整列状態で回転する配列です.
[1,2,3,4,5]
[2,3,4,5,1]
[3,4,5,1,2]
[4,5,1,2,3]
[5,1,2,3,4]
上記の大きさ5の配列の配置があるとする.
1.midIndexによる最小値の決定
mid = (start + end)/2;
やはりmidIndexを計算してから...最小値基準としての条件を考える.
  • 私は前のインデックスより小さい->私のインデックスは最小値です.
  • 私は後のインデックスより大きい->ポストインデックスは最小値です.
  • mid Indexによる前後検査後...バイナリナビゲーションを続行すればいいです.
    問題は探索区間を区分することである.
    2.バイナリナビゲーション領域の区分
    まず、回転配列で値を検索するようにセグメント化します.
  • 「start-mid」セグメント配列時
  • しかし、問題があります.上記の場合、
    [1,2,3,4,5]
    [2,3,4,5,1]
    [3,4,5,1,2]
    の配列の組み合わせ...「最小値1は、左と右の間によく区切られています.」start~end」セグメントが整列していれば、ナビゲーションセグメントを分割することは不可能です.
    では反対の場合...
  • 「mid~end」区間整列時は
  • である.
    [1,2,3,4,5]
    [4,5,1,2,3]
    [5,1,2,3,4]
    最小値1は左または中央に分布します.[4,5,1,2,3]なら上から判っているはずですが…この条件でバイナリナビゲーションを続行すればよい
    整理すると...
    「mid~end」セグメントが整列している場合は、start、(mid-1)セグメントバイナリナビゲーションを使用し、(mid+1)、endセグメントバイナリナビゲーションでない場合は使用できます.
            {
                int[] arr = new int[]{1, 2, 3, 4, 5};
    
                int idx = findMinIndex(arr, 0, arr.length - 1);
                assert (0 == idx);
    
                arr = new int[]{2, 3, 4, 5, 1};
    
                idx = findMinIndex(arr, 0, arr.length - 1);
                assert (4 == idx);
    
                arr = new int[]{3, 4, 5, 1, 2};
    
                idx = findMinIndex(arr, 0, arr.length - 1);
                assert (3 == idx);
    
                arr = new int[]{4, 5, 1, 2, 3};
    
                idx = findMinIndex(arr, 0, arr.length - 1);
                assert (2 == idx);
    
                arr = new int[]{5, 1, 2, 3, 4};
    
                idx = findMinIndex(arr, 0, arr.length - 1);
                assert (1 == idx);
            }
        public static int findMinIndex(int[] arr, int start, int end) {
            if (end <= start) {
                return start;
            }
    
            int mid = (start + end) / 2;
    
            if (start <= (mid - 1) && arr[mid - 1] > arr[mid]) {
                return mid;
            }
    
            if ((mid + 1) <= end && arr[mid] > arr[mid + 1]) {
                return mid + 1;
            }
    
            if (arr[mid] < arr[end]) {
                return findMinIndex(arr, start, mid - 1);
            }
    
            return findMinIndex(arr, mid + 1, end);
        }
    ソース-POCUアカデミーCOMP 3500コースの適用