剑指offer-test06

6.旋转数组的最小数字
三种方法,(题目的意思是输出整个数组的最小值。其中是一个非减排序。。说明:最小值位置是出现单调性改变

1、最笨的一种:
遍历整个数组,找出其中最小的数。这样肯定拿不到offer
2、稍微优化:时间复杂度O(n)
first-数组为空,返回0
second-一般情况部分旋转,例如由(1,2,3,4,5)旋转为(3,4,5,1,2),此时只需要遍历数组,找到当前数比前面的数小的数即可。
third-特殊情况需要完全旋转也就是没有旋转,例如由(1,2,3,4,5)旋转为(1,2,3,4,5),此时第一个数最小。返回array[0].

import java.util.ArrayList;
public class Solution {
	public int minNumberInRotateArray(int [] array) {
         //数组为空时
        if(array.length==0)  return 0;
        //前部分数据旋转
        for(int i=0;i<array.length-1;i++){
            if(array[i]>array[i+1])
                return array[i+1];
        }
        //全部数据旋转,相当于没有旋转,最小数即为第一个数
        return array[0];
	}
}


import java.util.ArrayList;
public class Solution {//输出旋转数组的最小元素
    public int minNumberInRotateArray(int [] array) {
        if(array.length==0)
            return 0;
        int min=array[0];
        for(int i=1;i<array.length;i++){
            if(min>array[i]){
                min=array[i];
                break;
            }
        }
        return min;
    }
}
以上这种完全忽略了旋转数组。其次数组有序的话应该考虑二分法

3、二分查找:时间复杂度为O(log(n))
查找时分三种情况:
1、array[mid] > array[high]:说明旋转后最小值在右区间,左边界设置low = mid + 1
2、array[mid] =array[high]:出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1],此时最小数字不好判断在mid左边还是右边,这时只好一个一个试 ,high = high - 1
3、array[mid] <array[high]:出现这种情况的array类似[2,2,3,4,5,6,6],此时最小数字一定就是array[mid]或者在mid的左边。因为右边必然都是递增的。 high = mid

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
           int low = 0 ; 
           int high = array.length - 1;   
           while(low < high){
               int mid = low + (high - low) / 2;        
               //如果中间值大于最后值,那么说明乱序的部分在后半段,所以在后半段寻找。可以使用mid+1是因为,中间值都比最后值大了,那还要它干嘛?
               if(array[mid] > array[high]){
                   low = mid + 1;
               }else if(array[mid] == array[high]){
                // 如果array=[1,0,1,1,1]或者[1,1,1,0,1],那没办法判断乱序子数组的位置,所以只能削减一步
                high = high - 1;
            }else{
              //如果中间值小于最后的值,说明后半部分为非减序列,所以在前半部分继续寻找;
                high = mid;
            }   
        }
        return array[low];
    }
}

二刷的问题:二分查找思路没有想到,直接都是使用了第二种方法。二分查找需要更加的熟悉。
中间值也可以表示为mid=(low+high)/2;
mid=low+(high-low)/2
返回值的时候可以直接return array[high];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值