二分查找实战:旋转数组最小值与缺失数字问题
1. 寻找旋转排序数组中的最小值
题目描述
已知一个升序排列的数组经过若干次旋转后,例如 [3,4,5,1,2],请找出其中的最小元素。假设数组中不存在重复元素。

解题思路 这道题的核心在于利用旋转数组的'二段性'。虽然整体不是有序的,但在旋转点两侧,大小关系是确定的。
想象一下,如果我们把数组首尾相连看成一个环,最小值就是那个'折点'。在二分查找中,我们需要找到一个判断标准,让搜索区间能不断缩小。通常有两种策略:
- 以右端点为基准:比较中间值
mid和右端点nums[right]。如果mid大于右端点,说明最小值在右侧(因为左半部分整体比右半部分大);否则最小值在左侧或就是mid。 - 以左端点为基准:比较中间值
mid和左端点nums[left]。逻辑类似,但需要注意处理数组未发生旋转的特殊情况。
当左右指针相遇时,即找到了目标位置。
代码实现(以右端点为参照) 这种方式逻辑相对直观,不需要额外判断是否旋转。
class Solution {
public:
int findMin(vector<int>& nums) {
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];
}
};
代码实现(以左端点为参照)
这种写法需要多一步特殊判断,因为如果数组本身有序,left 可能会指向最大值而非最小值。
class {
:
{
left = ;
right = nums.() - ;
(left < right) {
mid = left + (right - left + ) / ;
(nums[mid] >= nums[]) {
left = mid;
} {
right = mid - ;
}
}
(left == nums.() - ) {
nums[];
}
nums[left + ];
}
};





