旋转数组中的最小数字——剑指offer11

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

在这里插入图片描述

方法1 暴力

关键点:

1.正常排序的情况下,最小就是第一个;
2.旋转过的,则找出第一个数字小于前一个数字。

从下标为0的元素开始遍历;
每次进行比较,如果当前元素比相邻的下一元素大,则对应的下一个元素即为最小值;
如果遍历到最后一个元素都没有出现过上述情况,则下标为0的元素为最小元素。

var minArray = function(numbers) {
    if(numbers.length==1)
        return numbers[0];
    for(var i=1;i<numbers.length;i++){
        if(numbers[i]<numbers[i-1])
            return numbers[i];
    }
    return numbers[0];
};

方法2 排序

先排序,再输出第一个元素,就是最小的元素

var minArray = function(numbers) {
    var arr=numbers.sort(function(a,b){return a-b});
    return arr[0];
};

方法3 二分查找

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题目中给出的是半有序数组,虽然传统二分告诉我们二分只能用在有序数组中,但事实上,仍然可以使用二分思想。

思路:数组中最特殊的位置是左边位置 left 和右边位置 right,将它们与中间位置 mid 的值进行比较,进而判断最小数字出现在哪里。

用左边位置 left 和中间位置 mid 的值进行比较是否可以?
举例:[3, 4, 5, 1, 2] 与 [1, 2, 3, 4, 5] ,此时,中间位置的值都比左边大,但最小值一个在后面,一个在前面,因此这种做法不能有效地减治。

用右边位置 right 和中间位置 mid 的值进行比较是否可以?
举例:[1, 2, 3, 4, 5]、[3, 4, 5, 1, 2]、[2, 3, 4, 5 ,1],用右边位置和中间位置的元素比较,可以进一步缩小搜索的范围。

补充说明:遇到 nums[mid] == nums[right] 的时候,不能草率地下定结论最小数字在哪一边,但是可以确定的是,把 right 舍弃掉,并不影响结果。

var minArray = function(numbers) {
    var left=0;
    var right=numbers.length-1;
    if(right==0)
        return numbers[0];
    while(left<right){
        var mid=left+Math.floor((right-left)/2);
        if(numbers[mid]>numbers[right]){
            left=mid+1;
        }else if(numbers[mid]<numbers[right]){
            right=mid;
        }else{
            right--;
        }
    }
    return numbers[left];
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值