题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。

解题思路

将旋转数组对半分可以得到一个包含最小元素的新旋转数组,以及一个非递减排序的数组。新的旋转数组的数组元素是原数组的一半,从而将问题规模减少了一半,这种折半性质的算法的时间复杂度为 O(logN)(为了方便,这里将 log2N 写为 logN)。

此时问题的关键在于确定对半分得到的两个数组哪一个是旋转数组,哪一个是非递减数组。我们很容易知道非递减数组的第一个元素一定小于等于最后一个元素。

通过修改二分查找算法进行求解:

  • 当 nums[mid] <= nums[high] 时,表示 [mid, high] 区间内的数组是非递减数组,[low, mid] 区间内的数组是旋转数组,此时令 high = mid;
  • 否则 [mid + 1, high] 区间内的数组是旋转数组,令 low = mid + 1。
public int minNumberInRotateArray(int[] arr) {if (arr.length == 0) {return 0;}int low = 0;int high = arr.length - 1;while (low < high) {int mid = low + (high - low) / 2;// 注意此处比较的是后半段if (arr[mid] <= arr[high]) { high = mid;} else {low = mid + 1;}}return arr[low];
}

如果数组元素允许重复,会出现一个特殊的情况:nums[low] == nums[mid] == nums[high],此时无法确定解在哪个区间,需要切换到顺序查找。例如对于数组 {1, 1, 1, 0, 1},low、mid 和 high 指向的数都为 1,此时无法知道最小数字 0 在哪个区间。

public int minNumberInRotateArray(int[] arr) {if (arr.length == 0) {return 0;}int low = 0;int high = arr.length - 1;while (low < high) {int mid = low + (high - low) / 2;if (arr[low] == arr[mid] && arr[mid] == arr[high]) {return minNumber(arr, low, high);} else if (arr[mid] <= arr[high]) {high = mid;} else {low = mid + 1;}}return arr[low];
}private int minNumber(int[] arr, int low, int high) {for (int i = low; i < high; i++) {if (arr[i] > arr[i + 1]) {return arr[i + 1];}}return arr[low];
}

参考

CyC2018

转载于:https://www.cnblogs.com/yueshutong/p/11571495.html

算法题解:旋转数组的最小数字相关推荐

  1. leetcode算法题--旋转数组的最小数字

    原题链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/ 二分法 int minArray(ve ...

  2. 算法练习day20——190411(重建二叉树、斐波那契数列、跳台阶、矩形覆盖、变态跳台阶、旋转数组的最小数字、矩阵中的路径)

    1.重建二叉树 根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. preorder = [3,9,20,15,7].inorder = [9 ...

  3. 牛客题霸 [ 旋转数组的最小数字] C++题解/答案

    牛客题霸 [ 旋转数组的最小数字] C++题解/答案 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. NOT ...

  4. 11. 旋转数组的最小数字(剑指 Offer 题解Java版)

    文章目录 11. 旋转数组的最小数字 题目描述 题目链接 解题思路 可以借助下图理解过程 代码 11. 旋转数组的最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. ...

  5. 【LeetCode】剑指 Offer 11. 旋转数组的最小数字

    [LeetCode]剑指 Offer 11. 旋转数组的最小数字 文章目录 [LeetCode]剑指 Offer 11. 旋转数组的最小数字 一.遍历 二.二分法 总结 一.遍历 算法步骤: 遍历数组 ...

  6. 剑指Offer #06 旋转数组的最小数字(二分查找)| 图文详解

    题目来源:牛客网-剑指Offer专题 题目地址:旋转数组的最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小 ...

  7. 剑指offer——11.旋转数组的最小数字

    题目: 题1:实现快速排序 题2:年龄排序问题. 题3:旋转数组的最小数字 知识点: 快速排序算法,参考:https://blog.csdn.net/shujuelin/article/details ...

  8. 剑指offer——面试题8:旋转数组的最小数字

    剑指offer--面试题8:旋转数组的最小数字 Solution1: 自己想的复杂度为O(n)O(n)O(n)的算法,若用二分查找则: 1.代码复杂:2.最坏情况下的二分查找的时间复杂度亦为O(n)O ...

  9. 【剑指 Offe】11. 旋转数组的最小数字

    题目:剑指 Offer 11. 旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数 ...

  10. 【剑指 Offe】剑指 Offer 11. 旋转数组的最小数字

    目录标题 算法汇总 题目 关键点 代码 1.解体方法 - 二分法 思路 代码 时间和空间复杂度 2.解题方法,如暴力法 思路 代码 时间和空间复杂度 算法汇总 以下是所有算法汇总,包括GitHub源码 ...

最新文章

  1. Android studio 文件包名连在一起的处理方法
  2. iphone 使用ZBar 条码扫描
  3. 【转】BI 入门: 体系架构及相关技术
  4. 《信息学奥赛一本通》 高精度加法。输入两个正整数,求它们的和。
  5. java鼠标左键按下后拖动实现多选_鼠标拖拽多选功能
  6. centos 本地化配置
  7. C++设计模式-观察者模式
  8. Airtool 2 for Mac(Wi-Fi流量捕获工具)支持m1
  9. Python网页简单小爬虫
  10. 公共关系学试题与参考答案
  11. 按首字母排序(汉字、英文、数字)简单实现
  12. mysql nlssort_Oracle中文排序 NLSSORT
  13. 和陌陌一样,今天 Instagram 也在网页版上又迈了一步
  14. 曲线长、旋转图形表面积、旋转图形体积
  15. 低调的华丽:从服务器开发的角度认识 asp.net 中的回调技术
  16. Ty p e O R M框架
  17. 应用系统安全规范-自己想到和网络搜索到的点子记录整合一下
  18. Android实现简单的网页跳转
  19. 【Java】Annotation
  20. java乘法逆元与除法取模,关于数论乘法逆元及相关知识点

热门文章

  1. # 字符串从右往左查找_字符串匹配(搜索,查找)算法
  2. Spring框架(二) ---- bean的歧义性
  3. 关于CUDA和CuDNN配置的小问题
  4. SQL Server遗失管理权限账号密码怎么办?
  5. 每天一个linux命令(53)--ps命令
  6. thinkphp3.2自定义success及error跳转页面
  7. C#实现整数冒泡排序、选择排序
  8. tf.app.flags和tf.app.run的使用
  9. 进程控制:进程的创建、终止、阻塞、唤醒和切换
  10. 如何使用log4j记录日志