【剑斩OFFER】算法的暴力美学——寻找旋转排序数组中的最小值

一、题目描述

二、算法原理

这道题目很显然是有二段性的,所以把数组分成两个部分,如上图;既然是求最小的值,其实就是求二分查找的查找最左端的二分模板的一样的题目:
循环条件:left < right
求中间点的方式:int mid = left + ( right - left )/2
至于区域划分和 left 和 right 的移动问题上图已经讲述了,这里就不重复了。
这里有个问题:图片的 tmpi 内部能不能等于 arr [ left ]
答:不能,特殊实例:3 4 5 6 7,这个例子的没有旋转,当:
int tmpi = arr [ left ]
绿色区域:if:arr[ mid ] < tmpi right = mid
红色区域:else left = mid + 1
因为 tmpi = 3,所以不管 mid 落在那个区域,只会命中第二个条件:left = mid + 1
当:mid = 0 时,此时arr[mid]就是最小值,但是命中第二个条件之后 left = mid + 1,跳过最小值了,所以 tmpi = arr[ left ] 永远找不到最小值,只会找到最大值。
三、代码实现
class Solution {
public:int findMin(vector<int>& nums) {int left = 0, right = nums.size() - 1;int tmpi = nums[right];while(left < right){int mid = left + (right - left)/2;if(nums[mid] <= tmpi) right = mid;else left = mid + 1;}return nums[left];}
};
