剑指 Offer 11. 旋转数组的最小数字 ---力扣网

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

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

  • 方法1 :暴力解法,用for遍历所有元素,找出最小值,此方法没有用到题目给的递增排序的条件
//暴力解法
public static int minArray(int[] numbers){
    int min=Integer.MAX_VALUE;
    for (int i:numbers){
        if(min>=i){
            min=i;
        }
    }
    return min;
}
  • 方法2:用到"递增排序的数组的一个旋转"的条件,使用两个指针i(0~numbers.length-2)和j(i+1),对数组进行一次遍历,
  • 因为他原先是递增数组,即numbers[i]恒小于numbers[j],但经过一次旋转,他必定会有一次numbers[i]大于numbers[j],也就是拐点
  • 如果发现有numbers[i]大于numbers[j]则返回j,否则返回0;
//稍作优化双指针对比
public static int minArray(int[] numders){
    int i=0,j=1,min=0;
    while (j<numders.length){
        if(numders[i]>numders[j])min=j;
        j++;
        i++;
    }
    return numders[min];
}
  • 方法3:在方法2的基础下再次优化,只用一个指针z,倒叙遍历数组,则遍历情况应该单调递减,如果出现拐点,也就是后一个元素比前一个小,则是我们要找的最小值
//数组倒序
public static int minArray(int[] numbers) {
    int min= Integer.MAX_VALUE,z=numbers.length;
    while(min>=numbers[--z]){
        min=numbers[z];
        if(z==0)break;
    }
    return min;
}
  • 方法4:二分法,通过二分搜索思想,创建前指针i和后指针j,以及他们相加除二m,通过j元素和m元素比较
  • 因为是递增数组,所以当numbers[m]>numbers[j]则说明min在m+1~j之间;
  • 如果当numbers[m]<numbers[j]则说明min在i~m之间;
  • 当numbers[m]==numbers[j]时,j--即可;
//二分法
public static int minArray4(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[j];
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值