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

简介: AC 剑指 Offer 11. 旋转数组的最小数字

剑指 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]] 。

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

输入:numbers = [2,2,2,0,1]
输出:0

提示:
n == numbers.length
1 <= n <= 5000
-5000 <= numbers[i] <= 5000
numbers 原来是一个升序排序的数组,并进行了 1 至 n 次旋转

解题思路&代码

class Solution {
    /**
     * @Title: minArray
     * @Description: 二分查找
     * @author: itbird
     * @date 2022年3月15日 下午7:45:43
     * @param numbers
     * @return int 时间复杂度: O(logn) 空间复杂度: O(1)
     */
    public int minArray(int[] numbers) {
        if (numbers == null || numbers.length == 0) {
            return -1;
        }

        // 使用二分查找
        int min = binarySearch(0, numbers.length - 1, numbers);
        return min;
    }

    private int binarySearch(int left, int right, int[] numbers) {
        // 此处使用二分查找,最大的难点,在于数组现在是分为两个有序数组,所以针对于不同的情况,我们需要做处理

        while (left < right) {
            int mid = (left + right) / 2;
            if (numbers[right] > numbers[mid]) {
                // 如果右边大于中间,说明最小值在中间的左端,我们此时舍弃右半部分
                right = mid;
            } else if (numbers[right] < numbers[mid]) {
                // 如果右边小于中间,说明最小值在中间的右端,我们此时舍弃左半部分
                left = mid + 1;
            } else {
                // 如果右边的值等于中间的值,此时我们由于重复元素的存在,我们不能舍弃左右
                right--;
            }
        }
        return numbers[left];
    }

    /**
     * @Title: minArray
     * @Description: 暴力查找
     * @author: itbird
     * @date 2022年3月15日 下午7:45:43
     * @param numbers
     * @return int 时间复杂度: O(N) 空间复杂度: O(1)
     */
    public int minArray1(int[] numbers) {
        if (numbers == null || numbers.length == 0) {
            return -1;
        }

        int min = numbers[0];
        for (int i = 1; i < numbers.length; i++) {
            if (numbers[i] < min) {
                min = numbers[i];
            }
        }
        return min;
    }
}
目录
相关文章
|
SQL 测试技术 项目管理
轻松学习SQL外键约束的核心原理和实用技巧
轻松学习SQL外键约束的核心原理和实用技巧
|
JavaScript 测试技术 C#
【C#】【xUnit】【Moq】.NET单元测试Mock框架Moq初探!
在TDD开发模型中,经常是在编码的同时进行单元测试的编写,由于现代软件开发不可能是一个人完成的工作,所以在定义好接口的时候我们就可以进行自己功能的开发(接口不能经常变更),而我们调用他人的功能时只需要使用接口即可。
5538 0
|
12月前
|
API
阿里云短信服务文档与实际API不符
阿里云短信服务文档与实际API不符
|
7月前
|
JavaScript 前端开发 Java
Idea启动SpringBoot程序报错:Veb server failed to start. Port 8082 was already in use;端口冲突的原理与解决方案
本文解决了Idea启动SpringBoot程序报错:Veb server failed to start. Port 8082 was already in use的问题,并通过介绍端口的使用原理和操作系统的端口管理机制,可以更有效地解决端口冲突问题,并确保Web服务器能够顺利启动和运行。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
7月前
|
机器学习/深度学习 文字识别 开发者
使用OCR库Pix2Text执行p2t.recognize()时出现list index out of range的错误信息(附有Pix2Text识别图片内容和laTex公式的代码)
有时候报错并不是你代码有问题,源码出错也是很常见的情况,比如之前使用mxgraph也出现了不知名bug,最后也是修改的源码解决的。有疑问欢迎交流~ 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
11月前
|
存储 监控 关系型数据库
MySQL自增ID耗尽解决方案:应对策略与实践技巧
在MySQL数据库中,自增ID(AUTO_INCREMENT)是一种特殊的属性,用于自动为新插入的行生成唯一的标识符。然而,当自增ID达到其最大值时,会发生什么?又该如何解决?本文将探讨MySQL自增ID耗尽的问题,并提供一些实用的解决方案。
367 1
|
人工智能 自然语言处理
使用Kimi+Markmap总结文件内容生成思维导图原创
一份文件内容太长,完整阅读下来太费时间,但如果使用AI进行内容提炼,再总结成思维导图,方便快速看到这份文件的核心内容和主题结构,就会极大地节约时间,目前就可以使用Kimi+Markmap这两个工具,帮我们把ppt、word、pdf等文件内容快速总结成思维导图。
2376 8
使用Kimi+Markmap总结文件内容生成思维导图原创
|
vr&ar C语言
计算机网络:信道复用
计算机网络:信道复用
626 0
|
消息中间件 负载均衡 Kafka
Kafka如何实现点对点消息和发布订阅消息?
Kafka 可以同时支持点对点消息和发布订阅消息模型
1330 0
|
机器学习/深度学习 SQL 机器人
【论文速递】ISBI2022 - 通过点对点相互学习增强知识蒸馏
【论文速递】ISBI2022 - 通过点对点相互学习增强知识蒸馏
336 0
【论文速递】ISBI2022 - 通过点对点相互学习增强知识蒸馏