剑指Offer 旋转数组的最小数字


题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减序列的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
乍一看,觉得这个挺简单的。直接遍历就好,直接遍历的时间复杂度也只有O(n)。但后来想想还是还是用二分写一下吧,毕竟不是考试什么的,有时间的话还是尝试着效率更好的方法。
用pre和next分别指向开头和结尾的元素,用mid指向中间的元素
1.如果array[mid]小于array[next],即mid指向的元素还是在最小数字后面半段。把next指向mid
2.如果array[mid]大于array[pre],即mid指向的元素在最小数字前面的半段数组,所以把pre指向mid。
3.重新计算mid
当pre和next相邻时结束,输出后面的array[next]。
当我这样写完了之后发现,当数组直接以最小数字开头时是不正确的,例如{1,2,3,4}
所以改成了输出array[pre]和array[next]较小的一个。
然后由发现了新的问题:当数组为{1,1,1,0,1,1,1,1,1}这样时,用二分的方法没有办法判断,mid到底是属于前半段还是后半段,所以在这种情况下我任然使用了遍历。
代码如下:

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
     if( array == null || array.length == 0 ) return 0;
        if( array.length == 1 ) return array[0];
         
        int pre = 0;
        int next = array.length-1;
        int mid = (pre + next)/2;

        while(pre < next){
            //{1,0,1,1,1,1,1,1,1}||{1,1,1,1,1,1,0,1,1,1}
            if( array[pre] == array[mid] && array[pre]== array[next]){
            	int min = array[0];
            	for(int i =1;i<array.length;i++){
                	if( array[i] < min ) min = array[i];
            	}
            	return min;
        	}
            //二分
            if( pre == next -1) {
                return (array[pre]>array[next])?array[next]:array[pre];
            }
            if( array[pre] >= array[next]){
                if( array[mid] >= array[pre]){
                    pre = mid;
                    mid = (pre + next)/2;
                }else if( array[mid] <= array[next] ){
                    next = mid;
                    mid = (pre + next)>>1;
                }
            }else{
                return array[pre];
            }
              
        }
       return array[next];    
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值