二分查找实战:旋转数组最小值与缺失数字求解
23. 寻找旋转排序数组中的最小值
题目描述
给定一个升序排列的数组,该数组在某个未知的枢轴点进行了旋转。例如 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2]。请找出其中的最小元素。
算法思路
这道题的关键在于利用旋转数组的特性进行二分查找。虽然数组整体不是有序的,但我们可以观察到局部有序性:
- 如果中间元素
mid大于右端点right,说明最小值一定在mid的右侧(因为左半部分包含了较大的数)。此时区间收缩为[mid + 1, right]。 - 如果中间元素
mid小于或等于右端点right,说明最小值在mid左侧或者就是mid本身。此时区间收缩为[left, mid]。
当左右指针相遇时,即找到了最小值。
C++ 代码实现(以右端点为参照)
class Solution {
public:
int findMin(vector<int>& nums) {
// 选择 nums[n - 1] 作为参照物
int left = 0;
int right = nums.size() - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[nums.size() - 1]) {
left = mid + 1;
} else {
right = mid;
}
}
return nums[left];
}
};
C++ 代码实现(以左端点为参照)
另一种写法是以左端点为基准,逻辑略有不同,需要注意处理数组未旋转的情况。
class Solution {
public:
int findMin {
left = ;
right = nums.() - ;
(left < right) {
mid = left + (right - left + ) / ;
(nums[mid] >= nums[]) {
left = mid;
} {
right = mid - ;
}
}
(left == nums.() - ) {
nums[];
}
nums[left + ];
}
};


