当前位置: 首页 > news >正文

【剑指offer】旋转数组的最小数字

在这里插入图片描述

  • 👑专栏内容:剑指offer
  • ⛪个人主页:子夜的星的主页
  • 💕座右铭:前路未远,步履不停

目录

  • 一、题目描述
    • 1、题目
    • 2、示例
      • 示例1
      • 示例2
  • 二、题目分析
    • 1、暴力法
    • 2、二分法
  • 三、代码汇总
    • 1、暴力法
    • 2、二分法


一、题目描述

1、题目

剑指offer:旋转数组的最小数字

有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

2、示例

示例1

输入:[3,4,5,1,2]

输出:1

示例2

输入:[3,100,200,3]

输出:3

二、题目分析

1、暴力法

旋转数组的原数组是一个非降序数组,也就是说,原数组中的元素是按照从小到大的顺序排列的。当将一个非降序数组旋转后,我们可以把旋转数组分为两部分,一部分是最大的一段非降序子数组,另一部分是最小的一段非降序子数组。旋转数组的最小元素就在这两部分之间。比如,数组[3, 4, 5,1,2] 它的最大的一段非降序子数组是[3,4,5]最小的一段非降序子数组是[1,2] ,而最小元素就是最小的非降序子数组的第一个数。

所以说,非降序数组在旋转之后有一个特征,就是在遍历的时候,原始数组是非递减的,旋转之后,就有可能出现递减,而引起递减的数字,就是最小值。

class Solution {
public:
    int minArray(vector<int>& numbers) {
        int n = numbers.size();		//(1)
        int min = numbers[0];		//(2)
        for(int i = 1;i<n;i++) 		//(3)
        {
            if(numbers[i] < numbers[i-1])	//(4)
            {
                min = numbers[i];
                break;			//(5)
            }
        }
        return min;
    }
};

(1)获取旋转数组的长度

(2)让旋转数组中第一个元素为最小值

(3)从第二个元素开始遍历旋转数组

(4)如果当前元素比前一个元素小,证明引出现了递减,那么当前元素就是旋转数组的最小元素

(5)找到了最小元素,跳出循环

2、二分法

我们要知道一件事,暴力查找的过程,本质是排除的过程,但是暴力遍历一次只能排除一个,效率过低。既然是查找,我们就可以用二分查找法来缩减时间复杂度。

前面分析过,旋转数组的最小值位于非降序子数组和旋转子数组的交界处。所以,我们可以使用二分查找来查找旋转子数组的第一个元素,也就是最小值。旋转数组的最小值一定在数组的旋转点左侧或者就是旋转点。因此,在查找过程中,我们需要缩小查找区间,尽可能保留可能包含最小值的区间使用leftright指针确定查找区间,缩小区间的方式是根据mid的值与right的值的大小关系进行判断。如果numbers[mid]>numbers[right],说明最小值在mid的右侧,将left指针移动到mid+1的位置;如果numbers[mid]<numbers[right],说明最小值在mid的左侧或者就是mid,将right指针移动到mid的位置;如果numbers[mid] == numbers[right],说明可能是一个旋转点,也可能不是,将right指针移动一位。

图片来自:Krahets

class Solution {
public:
    int minArray(vector<int>& numbers) {
       int n = numbers.size();
       int left = 0,right = n-1;
       //二分查找
       while(left<right)
       {
           int mid = (left + right)/2;
           if(numbers[mid]>numbers[right])
                 left = mid + 1;
            else if (numbers[mid]<numbers[right])
                right = mid;
            else   
                right --;
       }
       return numbers[left];
    }
};

三、代码汇总

1、暴力法

class Solution {
public:
    int minArray(vector<int>& numbers) {
        int n = numbers.size();		
        int min = numbers[0];		
        for(int i = 1;i<n;i++) 	
        {
            if(numbers[i] < numbers[i-1])	
            {
                min = numbers[i];
                break;			
            }
        }
        return min;
    }
};

2、二分法

class Solution {
public:
    int minArray(vector<int>& numbers) {
       int n = numbers.size();
       int left = 0,right = n-1;
       //二分查找
       while(left<right)
       {
           int mid = (left + right)/2;
           if(numbers[mid]>numbers[right])
                 left = mid + 1;
            else if (numbers[mid]<numbers[right])
                right = mid;
            else   
                right --;
       }
       return numbers[left];
    }
};

相关文章:

  • 手写一个简单的RPC框架
  • 如何创建和编写项目管理计划?
  • 算法设计与分析 实验五 贪心算法
  • 正式环境关闭swagger
  • 动态内存的开辟
  • 【分布式版本控制系统Git】| IDEA 集成 Git 、IDEA 集成 GitHub
  • C语言指针链表
  • 全网最完整,接口测试总结彻底打通接口自动化大门,看这篇就够了......
  • 【JVM虚拟机面试宝典】JVM的内存结构是怎么样的?在JVM中会发生内存溢出的区域有那些?— day06
  • C++ string类
  • 细数那些惊艳一时的 CSS 属性
  • 【C语言】你真的了解结构体吗
  • 可做题2(矩阵快速幂,乘法逆元,exgcd)
  • Mysql用户权限分配详解
  • 一文7个步骤从0到1教你搭建Selenium 自动化测试环境
  • 【Leetcode】104. 二叉树的最大深度
  • 0基础学习移动端适配
  • 2017届校招提前批面试回顾
  • gcc介绍及安装
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • Hibernate【inverse和cascade属性】知识要点
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Java方法详解
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • PHP CLI应用的调试原理
  • Spring声明式事务管理之一:五大属性分析
  • vue-cli3搭建项目
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 从零开始的无人驾驶 1
  • 检测对象或数组
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 坑!为什么View.startAnimation不起作用?
  • 前端_面试
  • 我感觉这是史上最牛的防sql注入方法类
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (一)RocketMQ初步认识
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .libPaths()设置包加载目录
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET Core中的去虚
  • .net 按比例显示图片的缩略图
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • [bzoj4240] 有趣的家庭菜园
  • [IE编程] WebBrowser控件的多页面浏览(Tabbed Browsing)开发接口
  • [ISITDTU 2019]EasyPHP
  • [JS]变量
  • [LeetCode] 178. 分数排名
  • [LeetCode]Max Points on a Line
  • [lintcode easy]Maximum Subarray
  • [Linux]进程间通信(system V共享内存 | system V信号量)
  • [Python学习]总结一下Cygwin安装与进阶学习列表
  • [Web开发] 如何改变IE滚动条的颜色