Given a rotated sorted array, find the index of maximum value of the array in $O(\log{n})$
For example, rotate the array $[1, 2, 3, 4, 5, 6, 7, 8]$ three elements to the left,
we have $[4, 5, 6, 7, 8, 1, 2, 3]$
After the rotation, there are two partial array:[4 5 6 7 8] and [1 2 3], We can visualize the array as [in figure (3)].

We try to use similar binary search algorithm which is as following
1. divide the array to two even parts,e.g. left and right
2. do a recursive call on one part of the array that contains the key

$\square$ Q. How do we know the maximum value is on the left or on right side?

1. find the middle element of the array [int mid = (lo + hi)/2]
2. compare arr[lo] and arr[mid]

if arr[lo] < arr[mid], we know the maximum value is between [mid] and [hi], [see figure (4)]
arr[lo] = 4 and arr[mid] = 7
Otherwise, the maximum value is in the range of [lo] and [mid], [see figure (5)]
arr[lo] = 6 and arr[mid] = 1
arr[] = {4, 5, 6, 7, 8, 1, 2, 3} lo = 0, hi = 7 mid = (lo + hi)/2 = 3; arr[lo] = 4, arr[mid] = 7; arr[lo] < arr[mid] The maximum value is from arr[mid] to arr[hi]
                        // pseudocode
int findMaxIndex(int[] arr, int lo, int li) {
int mid = (lo + hi)/2;
if(arr[lo] < arr[mid])
return findMaxIndex(arr, mid, hi);
else
return findMaxIndex(arr, lo, mid);
}

There is one special case that we need to be considered if the array does not rotated at all, then above code will fail. for example, given [1, 2, 3, 4] However, we can just compare the most left and most right elements in the array
Note: If the array doesn't rotated, then $arr[lo] \lt arr[hi]$, otherwise $arr[lo] \geq arr[hi]$
                        if([lo] < [hi])
the array does not rotate at all,
the index of maximum value is [hi]


Better Code
                /**
1. arr = {1},
2. 2 1
mid = arr[0]
3. 1 2
mid = arr[0]

2 3 4 1  (lo=0, hi=3)
mid = 1
(lo=1, hi =3) -> 3 4 1
mid = 2
(lo=2, hi=3) -> 4 1
mid = 2
arr[2] < arr[2]
max(arr, lo=2, hi=2)  => 4

rotate sorted string
*/
public static int max(int[] arr, int lo, int hi){
if(arr[lo] <= arr[hi]){
return arr[hi];
}else{
int mid = (lo + hi)/2;
if(arr[lo] < arr[mid]){
return max(arr, mid, hi);
}else{
return max(arr, lo, mid);
}
}
}

Full implementation in Java
            // Find the index of minimum element of an array
// Make sure to test the case [2, 1]
public static int findMinimumIndex(int[] arr, int lo, int hi){
if( arr[lo] <= arr[hi])
return arr[lo];
else{
// [2, 1]
// [3, 1, 2]
// =>[3, 1] => [1]
int mid = (lo + hi)/2;
if(arr[lo] < arr[mid])
return findMinimumIndex(arr, mid, hi);
else if(arr[lo] > arr[mid])
return findMinimumIndex(arr, lo, mid);
}
}

public static int findMaximumIndex(int[] arr, int lo, int hi){
if(arr[lo] <= arr[hi])
return arr[hi];
else{
// [2, 1]
int mid = (lo + hi)/2;
if( arr[lo] < arr[mid])
return findMaximumIndex(arr, mid, hi);
else if(arr[lo] > arr[mid])
return findMaximumIndex(arr, lo, mid);
}
}

Following up Question, find the index of the minimum element from above array
                    // make sure check the case [2 1]
int findIndexMinimum array lo hi
// no rotation
if(array[lo] <= array[hi])
return lo
else
mid = lo + hi/2
if array[lo] < array[mid]
findIndexMinimum array mid+1 hi    // 2 1, 3 1 2
else
findIndexMinimum array lo mid