二分查找总结 & 进阶

题目描述:

  • leetcode 154. 寻找旋转排序数组中的最小值 II

题目链接:

  • 来源:力扣(LeetCode)
  • 链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii

解答:

class Solution {
public:
    int findMin(vector<int>& A) {
        if (A.size() == 0)
            return 404;
        /*
            二分查找问题解析:
                前提:要使用二分查找,必须是在 有序序列 上。
            传统二分:
                数组:A[0,...,n],有序数组。
                目标:找到给定的target值。
                边界:left = 开始下标,right = 结束下标,均可以访问,以防止越界。
                中间值:pivot = left + (right - left) / 2,防止数值溢出。
                终止:left <= right; 不一定能找到target值;"等于"是为了测试最后一个A[pivot]是否为target。
                左移规则:target > A[pivot]; left = pivot + 1;
                右移规则:target < A[pivot]; right = pivot - 1;

            当前题目:
                数组:A[0,...,n],前后半截有序数组。
                目标:找出最小值。
                边界:同上。
                中间值:同上。
                终止:left < right; 因为一定有最小值,当 left == right 时,即找到最小值。
                左移规则(详细阐述见代码):
                    A[pivot] > A[right]; left = pivot + 1;
                右移规则(详细阐述见代码):
                    A[pivot] < A[right]; right = pivot;
                    A[pivot] == A[right]; right -= 1;
        */
        

        int left = 0, right = A.size() - 1, pivot;
        while(left < right)
        {
            pivot = left + (right - left) / 2;

            /*
                旋转后数组的最后一个元素A[n]和最小值A[x],可以作为左右移动的判断依据。
                可以知道(多想想):
                A[x]值的左半部分都 >= A[n];
                A[x]值得右半部分都 <= A[n];
                eg: A[0] <= A[1] <= A[2] <= ... >= A[x] <= A[x+1] <= ... <= A[n] 
            */

            /* 取值A[pivot],大于最右边的值,证明A[pivot]在最小值A[x]的左边,需要则left右移 */
            if(A[pivot] > A[right]) 

            /* 这里 A[pivot] > A[right] 必定不是最小值,则left在pivot基础上右移1位*/
                left = pivot + 1;

            /* 取值A[pivot],小于最右边的值,证明A[pivot]在最小值A[x]的右边,需要则right左移*/
            else if (A[pivot] < A[right])

            /* 这里虽然 A[pivot] < A[right],需要right左移,但无法确定A[pivot]是否最小值,
            故right移动到pivot位置即可 */
                right = pivot; 

            /* 取值A[pivot] == A[right],无法判断A[pivot]在A[x]的左侧还是右侧,但仍可以确定
            需要right左移:因为A[pivot]在A[right]的左侧,A[pivot]可以作为A[right]是最小值的替代,
            同时,为了不会影响right在最右边作为比较的标准,将right只左移1位 */
            else 
                right -= 1;
        }
        /* return A[left] || return A[right] 均可 */
        return A[right]; 
    }
};

你可能感兴趣的:(编程代码题)