旋转数组中的最小数字
问题:旋转数组中的最小数字剑指 Offer 11. 旋转数组的最小数字 - 力扣(LeetCode)
二分法:数组旋转点之前的非递减序列 >= 旋转点之后的非递减序列;
m是二分的中点,向下取整;比较numbers[m] 和 numbers[j]的大小;
大于则旋转点在[m+1,j];小于则旋转点在[i,m];相等则 采取 - -j 缩小区间范围(或者直接遍历数组);
难点理解:相等时,旋转点可能在左边也可能 在右边;为缩小区间范围,将j 减小,有两种情况:
一种是x < j,则 - -j ,[i,j]仍包含旋转点,缩小范围是安全的;
另一种是 x = j,则 - -j 丢失旋转点,这时有且只有 [i,x]之间的元素相等,且[m,j]之间的元素也相等,[i,j]区间即为左排序数组,二分下去一定是相等的数,也是本轮的numbers[i] .
nums[x]=nums[j]=nums[m]≤number[i] ; i <= m < j =x ; 得出 m < x,那么numbers[m] >= numbers[i]
时间复杂度:O(log N) ; 空间复杂度:O(1)
class Solution { public: int minArray(vector<int>& numbers) { int i= 0,j = numbers.size()-1; while(i < j){ int m = (i+j)/2; if(numbers[m]>numbers[j]) i = m+1; else if(numbers[m] < numbers[j]) j = m; else --j; } return numbers[i]; } };
浙公网安备 33010602011771号