Find the minimum in a rotated array

Posted by chunyang on February 5, 2021

一个递增有序数组,在中间某个位置被旋转。在旋转的数组中找到最小值。

网上其实有很多题解,但是一直看不明白他们为什么和正常的二分查找不一致。其实本质上就是二分查找, 只不过我们需要处理好边界条件。

没有重复元素

int findMin(vector<int>& arr) {
    int start = 0, end = arr.size();
    while (start < end) {
        int mid = (end - start)/2 + start;
        if (mid > start && arr[mid] < arr[mid-1]) return arr[mid];
        else if (mid < end - 1 && arr[mid] > arr[mid+1]) return arr[mid+1];
        else {
            if (arr[start] <= arr[mid]) {
                if (arr[start] < arr[end-1]) return arr[start];
                start = mid + 1;
            } else {
                end = mid;
            }
        }
    }
    return arr[0];
}

有重复元素

int findMin(vector<int>& arr) {
    int start = 0, end = arr.size();
    while (start < end) {
        int mid = (end - start)/2 + start;
        if (mid > start && arr[mid] < arr[mid-1]) return arr[mid];  // 1
        else if (mid < end - 1 && arr[mid] > arr[mid+1]) return arr[mid+1];  // 2
        else {
            if (arr[start] < arr[mid]) {
                if (arr[start] < arr[end-1]) return arr[start];
                start = mid + 1;
            } else if (arr[start] > arr[mid]){
                // 如果 arr[mid] 是最小值,会在 2 出的 if 匹配掉返回
                end = mid;
            } else {
                ++start;
            }
        }
    }
    return arr[0];
}