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

旋转数组的最小数字 -- java

题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个 非递减 排序的数组的一个旋转,输出旋转数组的最小元素。例如数组 {3, 4, 5, 1, 2} 为 {1, 2, 3, 4, 5} 的一个旋转,该数组的最小值为 1。

NOTE:若数组大小为 0,请返回 0。

解题思路

如果遇到从排序的数组中查找数字需要尝试二分查找法。

我们利用两个指针分别指向数组的第一个元素和最后一个元素,我们可以先找到数组中间的元素,如果该中间元素大于或等于第一个元素,则位于前面的非递减子数组,此时我们就可以把第一个指针指向该中间元素,这样就可以缩小寻找的范围,移动以后,第一个指针依然指向前面的非递减数组;

否则属于后面的非递减子数组,此时我们就可以把第二个指针指向该中间元素,移动以后,第二个指针依然指向后面的非递减数组。然后循环下去,最终第一个指针将指向前面子数组的最后一个元素,而第二个指针将会指向后面子数组的第一个元素,而第二个指针指向的刚好是最小的元素。循环结束。

PS:我们要注意在参考解题中main函数里的特例,如果两个指针以及中间的元素指向的三个数字相等,就只能顺序查找。

代码

public class Min {
    /**
     * 获取旋转数组的最小数字
     * @param numbers 旋转数组
     * @return 最小数字
     * @throws Exception
     */
    public static int min(int[] numbers) throws Exception {
        if (numbers == null || numbers.length == 0) {
            throw new Exception("Invalid parameters");
        }
        int length = numbers.length;

        // index1永远为前一个非递减的数组指针
        int index1 = 0;
        // index2永远为后一个非递减的数组指针
        int index2 = length-1;
        // middle永远指向中间的值,当旋转数据就是原数组时,返回第1个数字
        int indexMid = index1;

        while (numbers[index1] >= numbers[index2]) {
            if (index2 - index1 == 1) {
                indexMid = index2;
                break;
            }

            indexMid = (index1 + index2) / 2;

            // 如果下标i, j, middle 指向的三个数字相等,就只能顺序查找
            if (numbers[index1] == numbers[index2] && numbers[index1] == numbers[indexMid]) {
                return minInOrder(numbers, index1, index2);
            }

            if (numbers[indexMid] >= numbers[index1]) {
                index1 = indexMid;
            } else if (numbers[indexMid] <= numbers[index2]) {
                index2 = indexMid;
            }
        }

        return numbers[indexMid];
    }

    /**
     * 顺序找出旋转数组中最小的值
     * 因为有序,只要找到第一个递减的值就可以返回了
     * @param numbers
     * @param index1
     * @param index2
     * @return
     */
    public static int minInOrder(int[] numbers, int index1, int index2) {
        int result = numbers[index1];
        for (int i = index1+1; i <= index2; i++) {
            if (result > numbers[i]) {
                result = numbers[i];
            }
        }
        return result;
    }

    // 测试
    public static void main(String[] args) throws Exception {
        int[] numbers = {3,4,5,1,2};
        System.out.println(min(numbers));
    }
}


来自:
《剑指Offer》
Coding-Interviews/旋转数组的最小数字.md at master · todorex/Coding-Interviews

相关文章:

  • 矩阵中的路径 -- java
  • 机器人的运动范围 -- java
  • pr字幕一个一个出现的笨方法
  • 绿色版premiere cs4无法导出(输出)解决方法
  • ip被禁止后访问网页403 易语言
  • Ext.String.format 的作用
  • 剪绳子 -- java
  • 二进制中1的个数 -- java
  • mysql 5.7修改root登录密码
  • 关于 Double.compare()
  • mac关闭f11显示桌面快捷键
  • java中如何比较两个浮点型大小
  • 了解 BigDecimal.valueOf(double val)与new BigDecimal(double val) 的区别
  • 数值的整数次方 -- java
  • Could not get a resource from the pool 的原因之一
  • express如何解决request entity too large问题
  • JS函数式编程 数组部分风格 ES6版
  • node学习系列之简单文件上传
  • Quartz初级教程
  • 从PHP迁移至Golang - 基础篇
  • 高程读书笔记 第六章 面向对象程序设计
  • 后端_MYSQL
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 突破自己的技术思维
  • 微信小程序:实现悬浮返回和分享按钮
  • 因为阿里,他们成了“杭漂”
  • 【干货分享】dos命令大全
  • (12)Hive调优——count distinct去重优化
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (6)添加vue-cookie
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (poj1.3.2)1791(构造法模拟)
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (笔试题)合法字符串
  • (九)c52学习之旅-定时器
  • (六)c52学习之旅-独立按键
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .gitignore文件—git忽略文件
  • .NET 5种线程安全集合
  • .Net FrameWork总结
  • .Net IE10 _doPostBack 未定义
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET6实现破解Modbus poll点表配置文件
  • .net打印*三角形
  • .NET的数据绑定
  • .net实现客户区延伸至至非客户区
  • .NET微信公众号开发-2.0创建自定义菜单
  • /bin/rm: 参数列表过长"的解决办法
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [Android Studio] 开发Java 程序
  • [AutoSar]BSW_Com02 PDU详解
  • [BZOJ 1040] 骑士