【LeetCode】剑指 Offer 11. 旋转数组的最小数字 p82 -- Java Version

news2024/11/26 12:28:25

题目链接:https://leetcode.cn/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/

1. 题目介绍(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 次旋转

【相同题目】:

注意:本题与 154. 寻找旋转排序数组中的最小值II 相同

2. 题解

2.1 穷举起手 – O(n)

时间复杂度O(n),空间复杂度O(1)

人狠话不多,起手就穷举,简单又易懂,大力有奇效。

class Solution {
    // 第一种方法:穷举
    public int minArray(int[] numbers) {
        int min = numbers[0];
        for (int i = 1; i < numbers.length; i++){
            if (numbers[i] <= min){
                min = numbers[i];
            }
        }
        return min;
    }
}

在这里插入图片描述

2.2 二分法 – O(logn)

时间复杂度O(logn),空间复杂度O(1)

在这里插入图片描述
二分清晰但略微麻烦,定义头尾索引,循环缩进,不断缩小范围,逼近最小值,但存在两个特例:

  1. 数组本身,即把一个数组的前0个元素搬到数组的末尾,如 [1,2,3,4,5];
  2. nums[start] = nums[mid] = nums[end],如出现[1,0,1,1,1]时,找不到最小值0,而是会返回1,因此当该情况方式时,我们将采用顺序遍历的方式,在start到end比较找出最小值。
class Solution {
    // 第二种方法:二分法
    public int minArray(int[] numbers) {
        // 1. 判空
        if (numbers == null || numbers.length <= 0) return -1;

        // 2. 初始化头索引、尾索引、中值索引
        int start = 0;
        int end = numbers.length-1;

        // 3. 初始化mid为start,是为了防止出现未旋转的特例,即把一个数组的前0个元素搬到数组的末尾(数组本身)
        int mid = start;

        // 4. 循环结束条件:start指到了最小值的前一个元素,end指到了最小值
        while (numbers[start] >= numbers[end]){
            if (end - start == 1) {
                mid = end;
                break;
            }
            
            // 5. 计算中点
            mid = (start + end)/2;
            
            // 7. 特例:当出现[1,0,1,1,1],这种start=mid=end的情况,就无法正确判断最小值了,所以这里我们让它去顺序遍历,找出最小值
            if (numbers[start] == numbers[mid] && numbers[end] == numbers[mid]) return minForAll(numbers,start,end);

            // 6. 与中点比较,不断缩小范围
            if (numbers[start] <= numbers[mid]){
                start = mid;
            } else if (numbers[end] >= numbers[mid]){
                end = mid;
            }
        }
        return numbers[mid];
    }

    // 顺序遍历,找出start到end范围内的最小值
    public int minForAll(int[] numbers,int start, int end){
        int min = numbers[start];
        for (int i = start; i <= end; i++){
            if (numbers[i] <= min){
                min = numbers[i];
            }
        }
        return min;
    }
}

在这里插入图片描述

二分改进:

  • 时间复杂度O(logn),在特例情况下(例如 [1,1,1,1])会退化到O(n)
  • 空间复杂度O(1)
    在这里插入图片描述
class Solution {
    public int minArray(int[] numbers) {
        int i = 0, j = numbers.length - 1;
        while (i < j) {
            int m = (i + j) / 2;
            if (numbers[m] > numbers[j]) i = m + 1;
            else if (numbers[m] < numbers[j]) j = m;
            else {
                int x = i;
                for(int k = i + 1; k < j; k++) {
                    if(numbers[k] < numbers[x]) x = k;
                }
                return numbers[x];
            }
        }
        return numbers[i];
    }
}

在这里插入图片描述

2.3 库函数求解 – O (n*log (n))

时间复杂度O (n*log (n)),空间复杂度O(1)

除此之外,还可以采用Stream,以及Collection求解最大/最小值

class Solution {
    // 第三种方法:库函数
    public int findMin(int[] numbers) {
        Arrays.sort(numbers);
        return numbers[0];
    }
}

在这里插入图片描述

3. 参考资料

[1] 面试题11. 旋转数组的最小数字(二分法,清晰图解)-- 图片来源 & 二分改进来源
[2] 【算法基础】Java如何使用库函数得出一个数组的最大/最小值?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/364966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于微前端,你想知道的都在这!

更多请关注微前端专题 https://codeteenager.github.io/Micro-Frontends/ 介绍 微前端官网&#xff1a;https://micro-frontends.org/ 问题&#xff1a;如何实现多个应用之间的资源共享&#xff1f; 之前比较多的处理方式是npm包形式抽离和引用&#xff0c;比如多个应用项目之…

浅谈Redisson实现分布式锁的原理

1.Redisson简介 Redis 是最流行的 NoSQL 数据库解决方案之一&#xff0c;而 Java 是世界上最流行&#xff08;注意&#xff0c;我没有说“最好”&#xff09;的编程语言之一。虽然两者看起来很自然地在一起“工作”&#xff0c;但是要知道&#xff0c;Redis 其实并没有对 Java…

windows共享文件夹(目录)(SMB服务)

SMB服务&#xff0c;文件共享服务&#xff0c;俗称文件夹&#xff08;目录&#xff09;、打印机等共享 一、创建共享用户 windos系统中&#xff0c;文件夹共享需要设置指定用户与密码&#xff0c;通过输入用户和密码进行连接&#xff0c;在设置共享时系统中有Everyone所有人设…

【Linux学习笔记】1.Linux 简介及安装

前言 本章介绍Linux及其安装方法。 Linux 简介 Linux 内核最初只是由芬兰人林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;在赫尔辛基大学上学时出于个人爱好而编写的。 Linux 是一套免费使用和自由传播的类 Unix 操作系统&#xff0c;是一个基于 POSIX 和 UNIX 的多…

【基础语法】JavaScript 全栈体系(四)

JavaScript 基础 第五章 类型转换 一、为什么需要类型转换&#xff1f; JavaScript是弱数据类型&#xff1a; JavaScript也不知道变量到底属于那种数据类型&#xff0c;只有赋值了才清楚。 坑&#xff1a; 使用表单、prompt 获取过来的数据默认是字符串类型的&#xff0c;此…

JVM及其内存模型

目录儿一、JVM1.1 为什么需要JVM&#xff1f;1.2 JVM内存模型1.3 堆&#xff08;Heap&#xff09;1.4 方法区&#xff08;Method Area&#xff09;1.5 虚拟机栈(JVM Stack)1.6 本地方法栈(Native Stack)1.7 程序计数器&#xff08;PC Register&#xff09;一、JVM JVM是Java V…

I-Cache 和 D-Cache

定义ICache和DCache是一种内存&#xff0c;虽然目前接触了好几种内存&#xff0c;寄存器&#xff0c;DDR等&#xff0c;它们在物理上的工作原理虽然不同&#xff0c;但是访问属性却很像。在速度上CPU > 寄存器 > Cache > SRAM &#xff1e;&#xff30;&#xff33;&…

100种思维模型之六顶帽思维模型-018

工作中&#xff0c;经常开会&#xff0c;开会于工作当然无可厚非。 可是&#xff0c;现实中的会议&#xff0c;往往存在效率低&#xff0c;效果不佳的问题。如&#xff0c;连续开一天的研究讨论会&#xff0c;最后没能讨论出个所以然&#xff0c;又或者会议有了决策&#xff0c…

QT_dbus(ipc进程间通讯)

QT_dbus(ipc进程间通讯) 前言&#xff1a; 参考链接&#xff1a; https://www.cnblogs.com/brt3/p/9614899.html https://blog.csdn.net/weixin_43246170/article/details/120994311 https://blog.csdn.net/kchmmd/article/details/118605315 一个大型项目可能需要多个子程序同…

《计算机网络:自顶向下方法》实验5:ARP协议分析 Wireshark实验

实验13:ARP协议分析 1 What is the 48-bit Ethernet address of your computer? 00:d0:59:a9:3d:68 2 What is the 48-bit destination address in the Ethernet frame? Is this the Ethernet address of gaia.cs.umass.edu? (Hint: the answer is no). What device has …

推荐算法—widedeep原理知识总结代码实现

wide&deep原理知识总结代码实现1. Wide&Deep 模型的结构1.1 模型的记忆能力1.2 模型的泛化能力2. Wide&Deep 模型的应用场景3. Wide&Deep 模型的代码实现3.1 tensorflow实现3.2 pytorch实现今天&#xff0c;总结一个在业界有着巨大影响力的推荐模型&#xff0c…

设计模式.工厂模式.黑马跟学笔记

设计模式.工厂模式4.创建型模式4.2 工厂模式4.2.1 概述4.2.2 简单工厂模式4.2.2.1 结构4.2.2.2 实现4.2.2.4 优缺点4.2.2.3 扩展4.2.3 工厂方法模式4.2.3.1 概念4.2.3.2 结构4.2.3.3 实现4.2.3.4 优缺点4.2.4 抽象工厂模式4.2.4.1 概念4.2.4.2 结构4.2.4.2 实现4.2.4.3 优缺点4…

C语言进阶(六)—— 结构体

1. 结构体基础知识1.1 结构体类型的定义struct Person{char name[64];int age; };typedef struct _PERSON{char name[64];int age; }Person;注意&#xff1a;定义结构体类型时不要直接给成员赋值&#xff0c;结构体只是一个类型&#xff0c;编译器还没有为其分配空间&#xff0…

【Kubernetes 入门实战课】Day02——初识容器

系列文章目录 【Kubernetes 入门实战课】Day01——搭建kubernetes实验环境(一) 文章目录系列文章目录前言一、Docker的诞生二、Docker的形态1、Docker Desktop2、Docker Engine二、Docker的安装1、服务器连接外网安装2、服务器不通外网三、Docker的使用三、Docker的架构总结前…

JavaWeb11-死锁

目录 1.死锁定义 1.1.代码演示 1.2.使用jconsole/jvisualvm/jmc查看死锁 ①使用jconsole&#xff1a;最简单。 ②使用jvisualvm&#xff1a;&#xff08;Java虚拟机&#xff09;更方便&#xff0c;更直观&#xff0c;更智能&#xff0c;更高级&#xff0c;是合适的选择。 …

Melis4.0[D1s]:2.启动流程(GUI桌面加载部分)跟踪笔记

文章目录0. 控制台输出信息等级设置0.1 设置log level 4 无法正常启动1.宏观启动流程1.1 控制台入口函数finsh_thread_entry()执行《startup.sh》1.2 《startup.sh》启动桌面GUI模块1.2.1 《startup.sh》加载 desktop.mod1.2.2 desktop.mod加载 init.axf1.2.3 init.axf 介绍1.…

C#与三菱PLC MC协议通信,Java与三菱PLC MC协议通信

三菱PLC的MC协议是一种常用的通信协议&#xff0c;用于实现三菱PLC与其他设备之间的通信。以下是一些关于MC协议的基本信息&#xff1a;协议格式MC协议的通信数据格式如下&#xff1a;数据头网络编号PC编号目标模块IO编号目标模块站号本机模块IO编号本机模块站号请求数据长度请…

Linud SSH与SCP的配置

目录 配置SSH协议 配置服务器通过密钥进行认证 配置SCP完成文件传输 ssh协议讲解 SSH协议理论讲解_静下心来敲木鱼的博客-CSDN博客https://blog.csdn.net/m0_49864110/article/details/128500490?ops_request_misc%257B%2522request%255Fid%2522%253A%2522167704203816800…

不加大资金投入,仅凭智能名片如何解决企业营销难题的?

中国90%以上的中小企业想要竞争和发展&#xff0c;就必须推广自己的品牌&#xff0c;提高自己的知名度。在小程序之前&#xff0c;APP是主流&#xff0c;但大多数中小企业负担不起APP的开发和昂贵的营销成本。 进入微信互联网时代后&#xff0c;为了帮助企业以更低的成本获得…

浙大MEM现场小组复试经验分享

作为2019年上岸浙大MEM项目的学姐一枚&#xff0c;很高兴收到杭州达立易考教育老师的邀请&#xff0c;给大家分享下现场面试的经历。先来看下复试流程是怎么样的。1、体检所有考生须参加。体检需在复试前完成&#xff08;未体检考生不得参加复试&#xff09;。 2、资格审查&…