欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > 剑指offer10_旋转数组的最小数字

剑指offer10_旋转数组的最小数字

2025/5/29 6:50:10 来源:https://blog.csdn.net/m0_71425418/article/details/148237625  浏览:    关键词:剑指offer10_旋转数组的最小数字

旋转数组的最小数字


把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

输入一个升序的数组的一个旋转,输出旋转数组的最小元素。

例如数组 {3,4,5,1,2}为 {1,2,3,4,5} 的一个旋转,该数组的最小值为 1。

数组可能包含重复项。

注意:数组内所含元素非负,若数组大小为 0,请返回 −1。

数据范围

数组长度 [0,90]。

样例
输入:nums = [2, 2, 2, 0, 1]输出:0

题解
  1. 预处理
    首先处理数组末尾与首元素相同的元素,以消除末尾水平段对二分查找的影响。例如,数组 [3,3,1,3] 处理后会变为 [3,3,1]
  2. 完全单调判断
    若处理后的数组满足 nums[end] >= nums[0],说明数组未被旋转或已完全单调,直接返回首元素。
  3. 二分查找
    二分查找的目标是找到旋转点(即最小值的位置)。根据以下条件调整边界:
    • nums[mid] < nums[0],说明 mid 位于右半段(旋转后的较小部分),将右边界设为 mid
    • 否则,将左边界设为 mid + 1
复杂度分析
  • 时间复杂度
    • 预处理阶段最坏需要遍历整个数组(例如所有元素相同),时间复杂度为 O ( n ) O(n) O(n)
    • 二分查找的时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)
    • 总时间复杂度为 O ( n ) O(n) O(n)
  • 空间复杂度
    仅使用常数空间,复杂度为 O ( 1 ) O(1) O(1)
class Solution {
public:int findMin(vector<int>& nums) {int n = nums.size() - 1;if (n < 0) return -1; // 处理空数组// 删除末尾与首元素相同的元素while (n > 0 && nums[n] == nums[0]) n--;// 若数组完全单调,直接返回首元素if (nums[n] >= nums[0]) return nums[0];// 二分查找最小值int l = 0, r = n;while (l < r) {int mid = (l + r) >> 1; // 等价于 (l + r) / 2if (nums[mid] < nums[0]) r = mid;else l = mid + 1;}return nums[r];}
};
代码解释
  1. 预处理
    通过 while 循环删除末尾与首元素相同的元素,例如 [3,3,1,3] 变为 [3,3,1]
  2. 完全单调判断
    若处理后的数组满足 nums[end] >= nums[0](例如 [1,2,3,4]),说明未被旋转,直接返回首元素。
  3. 二分查找
    • 循环条件l < r 确保区间最终收敛到单个元素。
    • 中间值计算mid = (l + r) >> 1 取中间位置。
    • 边界调整:若 nums[mid] < nums[0],说明最小值在左半段(包含 mid),否则在右半段(mid + 1 开始)。
    • 返回值:最终 r 指向最小值的位置。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词