剑指 Offer 11. 旋转数组的最小数字

剑指 Offer 11. 旋转数组的最小数字

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

给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。

注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。

输入:numbers = [3,4,5,1,2]
输出:1

方法

  1. 暴力

    直接遍历数组,找到最小值

    int minArray(vector<int>& numbers) {
    int m = INT_MAX;
    for (auto i : numbers)
    m = min(m, i);
    return m;
    }
    • 时间复杂度: O(n) n为数组长度
    • 空间复杂度: O(1)
  2. 优化暴力
    根据题意描述,原数组是一个升序的数组, 当发现当前元素比前一个元素小的时候,说明这是原数组的首元素,即最小值

    int minArray(vector<int>& numbers) {
    for (int i = 1; i < numbers.size(); i ++) {
    if (numbers[i] < numbers[i - 1]) return numbers[i];
    }
    return numbers[0];
    }
    • 时间复杂度: O(N)
    • 空间复杂度: O(1)
  3. 二分
    二分性质: 左排序数组任一元素 >= 右排序数组任一元素

    int minArray(vector<int>& numbers) {
    int l = -1, r = numbers.size() - 1;
    while( l + 1 != r) {
    int mid = (l + r) >> 1;
    if (numbers[mid] > numbers[r]) l = mid; // numbers[mid]在左排序区间
    else if (numbers[mid] < numbers[r]) r = mid; // numbers[mid]在右排序区间
    else r -= 1; // 无法判断numbers[mid]在左区间还是右区间
    }
    return numbers[r];
    }
    • 时间复杂度: O(logN)
    • 空间复杂度: O(1)

posted on   SocialistYouth  阅读(4)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人

统计

点击右上角即可分享
微信分享提示