每日一题——寻找旋转排序数组中的最小值(I)

寻找旋转排序数组中的最小值——I

题目链接

每日一题——寻找旋转排序数组中的最小值(I)_第1张图片


思路

首先我们以数组[1,2,3,4,5,6,7]举个例子,经过旋转后它无非就这两种情况

情况一:旋转过后数组变成两段有序数列

每日一题——寻找旋转排序数组中的最小值(I)_第2张图片

情况二:旋转过后数组不变,仍然有序

而这两种情况都有一个共性

以数组**最右边的值val**为研究对象,最小值1右边的所有数必定小于val;最小值左边的数必定大于val

我们可以画出如下的折线图来总结:

每日一题——寻找旋转排序数组中的最小值(I)_第3张图片

知道了这些后,我们就可以利用二分法求解了:

  • 我们设左边界为left,右边界为right,左右边界的中间值为mid
  • 由上面的分析可以知道,若nums[mid] > nums[right],就说明最小值一定在中间值的右侧,中间值左侧的区域直接舍弃即可:

每日一题——寻找旋转排序数组中的最小值(I)_第4张图片

  • nums[mid] < nums[right],就说明最小值一定在中间值的左侧或者就是中间值,中间值右侧的区域直接舍弃即可:

每日一题——寻找旋转排序数组中的最小值(I)_第5张图片

  • 随着区间的不断缩小,leftright最终就会相等,其最后停留的位置也就是数组的最小值

实现代码

int findMin(int* nums, int numsSize) {
    int left = 0;
    int right = numsSize - 1;

    while (left < right)
    {
        int mid = (right - left) / 2 + left;

        //如果中间值大于最右边的值,那么最小值一定在中间值的右边
        if (nums[mid] > nums[right])
            left = mid + 1;
        //否则,最小值就在最右边的值的左边,也可能就是这个中间值
        else
            right = mid;
    }

    //循环结束时,left和right所在的位置就是最小值的位置
    return nums[left];
}

你可能感兴趣的:(每日一题,#,数组相关,算法,leetcode,c语言)