剑指 Offer 11. 旋转数组的最小数字https://leetcode.cn/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/
- 通过 二分查找 将时间复杂度降到 O(logn)
- 左边的元素比 nums[n - 1] 大,右边的元素比 nums[n - 1] 小
- 但要注意有比较多的特殊情况,此时可能退化成线性查找,时间复杂度为 O(n)
int minArray(vector<int>& numbers) {
int n = numbers.size();
// 二分查找
int left = 0, right = n - 1;
while (left < right) // !!!
{
int mid = left + (right - left) / 2;
int midVal = numbers[mid];
if (midVal < numbers[n - 1])
{
right = mid; // !!!
}
else if (midVal > numbers[n - 1])
{
left = mid + 1;
}
else // 可能出现从连续数字中间发生的旋转,退化成线性查找
{
int res = numbers[left];
for (int i = left + 1; i <= right; ++i)
{
res = min(res, numbers[i]);
}
return res;
}
}
return numbers[left];
}
测试用例
[1,1,1,1]
[3,1,3]
[3,3,3,3,3,3,5,1,3]
[3,5,1,3,3,3,3,3,3]