剑指offer Java版 面试题11:旋转数组的最小数字

题目描述

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

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

测试用例

  • 功能测试(输入的数组是非递减排序数组的一个旋转,数组中有重复的数字或者没有重复的数字)
  • 边界值测试(输入的数组是一个非递减排序的数组,只包含一个数字的数组)
  • 特殊输入测试(输入空指针)

题目考点

  • 考察应聘者对二分查找的理解。如果遇到从排序的数组中查找数字需要尝试二分查找法。
  • 考察应聘者的沟通能力和学习能力。如果面试官提出新的概念,那么我们可以主动和面试官沟通,多问几个问题,把概念弄清楚。
  • 考察应聘者思维的全面性。排序数组本身是一个数组旋转的一个特例,另外,我们需要考虑到数组中有相同数字的特例。

解题思路

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

我们利用两个指针分别指向数组的第一个元素和最后一个元素,我们可以先找到数组中间的元素,如果该中间元素大于或等于第一个元素,则位于前面的非递减子数组,此时我们就可以把第一个指针指向该中间元素,这样就可以缩小寻找的范围,移动以后,第一个指针依然指向前面的非递减数组;否则属于后面的非递减子数组,此时我们就可以把第二个指针指向该中间元素,移动以后,第二个指针依然指向后面的非递减数组。然后循环下去,最终第一个指针将指向前面子数组的最后一个元素,而第二个指针将会指向后面子数组的第一个元素,而第二个指针指向的刚好是最小的元素。循环结束。

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

Picture1.png

image-20201128151251772

image-20201128151313476

代码

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 j--;
        }
        return numbers[i];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值