剑指Offer-11:旋转数组的最小数字

本文探讨了如何优化解决旋转数组中最小元素的问题,避免了传统二分查找的效率瓶颈,通过实例和正确代码实现,重点讲解了在特殊情况下如何进行顺序查找。

题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

示例 1:

输入:[3,4,5,1,2]
输出:1
示例 2:

输入:[2,2,2,0,1]
输出:0
思路:我们发现旋转后的数组可以划分为两个排序的子数组,并且前边子数组的元素全部大于等于后边子数组的元素,并且刚好最小的元素就是这两个子数组的分界线,而我们的目的就找到和这个分界线,所以我们可以用二分查找
解答:

public int findMin(int[] nums){
        if (nums==null ||nums.length==0)
            return -1;
        
        int len=nums.length;
        int left=0;
        int right=len-1;
        
        int index=left;//防止一个排好的数组
        while (nums[left]>=nums[right]){
            if(right-left==1)
                return nums[right];
            
            index=(left+right)/2;
            
            //让他俩不断的忘中间靠
            if (nums[index]>=nums[left]){//在左边递增数组里
                left=index;
            }else if(nums[index]<=nums[right]){//在右边递增数组里
                right=index;
            }
        }
        return nums[right];
    }

以上的方法在LeetCode上提交会超时!并且没有考虑极端的情况!
假设我么你的数组是{0 1 1 1 1} 的旋转数组{1 0 1 1 1 }或者{1 1 1 0 1},在这两个数组中 ,他们的第一个数组和最后一个数字还有中间的数组 都是数字1,那程序在执行判断时就不知道中间的数字1 是前边的数组还是后边的数组了,所以在这种情况下 我们只能顺序查找!

所以正确的代码应该是酱:

public int findMin(int[] nums){
        if (nums==null ||nums.length==0)
            return -1;
        
        int len=nums.length;
        int left=0;
        int right=len-1;
        
        int index=left;//防止一个排好的数组
        while (nums[left]>=nums[right]){
     	   //如果找到分界线了
            if(right-left==1)
                index=right;
            
            index=(left+right)/2;
          
            //如果都一样无法判断的话 只能顺序查找了!
            if (nums[left]==nums[right]&&nums[right]==nums[index]){
                int result=nums[left];
                for (int i = left+1; i <=right; i++) {
                    if (result>nums[i])
                        result=nums[i];
                }
                
            }
            //让他俩不断的忘中间靠
            if (nums[index]>=nums[left]){//在左边递增数组里
                left=index;
            }else if(nums[index]<=nums[right]){//在右边递增数组里
                right=index;
            }
        }
        return nums[right];
    }

okok 就这样,今天好困好困~~睡了睡了···

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值