寻找旋转排序数组中的最小值——I
思路
首先我们以数组[1,2,3,4,5,6,7]
举个例子,经过旋转后它无非就这两种情况:
情况一:旋转过后数组变成两段有序数列:
情况二:旋转过后数组不变,仍然有序:
而这两种情况都有一个共性:
以数组**最右边的值
val
**为研究对象,最小值1
右边的所有数必定小于val
;最小值左边的数必定大于val
我们可以画出如下的折线图来总结:
知道了这些后,我们就可以利用二分法求解了:
- 我们设左边界为
left
,右边界为right
,左右边界的中间值为mid
- 由上面的分析可以知道,若
nums[mid] > nums[right]
,就说明最小值一定在中间值的右侧,中间值左侧的区域直接舍弃即可:
- 若
nums[mid] < nums[right]
,就说明最小值一定在中间值的左侧或者就是中间值,中间值右侧的区域直接舍弃即可:
- 随着区间的不断缩小,
left
和right
最终就会相等,其最后停留的位置也就是数组的最小值
实现代码
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]; }