leetcode--旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [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

方法一:

分析:先让数组排序,然后再取第一个元素

Array.sort()

对数组元素进行排序

概要

array.sort()

array.sort(orderfunc)

参数

orderfunc:用来指定如何排序的可选函数

返回值

该数组的引用。注意是在原数组中进行排序,没有新建数组

描述

sort()方法在原数组中对数组元素进行排序,没有创建新数组。如果在调用sort()时不带参数,将按字母顺序(更精确地说,是字符编码顺序)对数组中的元素进行排序。要实现这一点,首先要把元素转化为字符串(如果有必要的话),以便进行比较

如果想按照其他顺序来进行排序,就必须提供比较函数,该函数要比较两个值,然后返回一个数字来表明这两个值的相对顺序。比较函数需要接受两个参数a和b,并返回如下值

  • 一个小于0的值。在这种情况下,表示根据排序标准,a小于b,在排序后的数组中,a应该排列在b的前面
  • 0。在这种情况下,a和b是相等的
  • 一个大于0的值。在这种情况下,a大于b。

注意:数组中的undefined元素会始终排列在数组末尾。即便提供了自定义的比较函数,也是如此,因为underfined值不会传递给提供的orderfunc。

示例

下面的代码展示了如何书写一个比较函数,来使得对一个数值按数值排序,而不是按字母排序:

//用于数值排序的排序函数
function numberorder(a,b){ return a-b}
a=new Array(33,4,222,1111);
a.sort();//字母排序:1111,222,33,4
a.sort(numberorder);//数值排序:4,33,222,1111

代码

/**
 * @param {number[]} numbers
 * @return {number}
 */
var minArray = function(numbers) {
    return numbers.sort(function(a,b){
        return a-b
    })[0]
};

方法二:

分析:使用二分法来遍历数组

思路:

  1. 取数组leftright之间的中点midleft为0,right为数组长度-1,mid向下取整
  2. numbers[mid]numbers[right]比较(这里为什么不能让numbers[mid]numbers[left]比较?原因很简单,举个例子:给出两个旋转数组[1,1,1,0,1],[2,0,2,2,2],对于这两个数组,第一个数组的最小值0位于midright的区间,第二个数组的最小值0位于leftmid的区间,单从这两个数组来看,就不能很好得看出最小值在哪个区间,所以选择让numbers[mid]numbers[left]作比较)
  3. 如果numbers[mid]>numbers[right],说明最小值在数组midright之间的区间,让left=mid+1
  4. 如果numbers[mid]<numbers[right],说明最小值在数组leftmid之间的区间,让right=mid
  5. 如果numbers[mid]==numbers[right],不能判断最小值在哪个区间


    这个时候需要让right自减,即缩小数组区间范围,提高精度(为什么不让left自增?如果让left自增,遇到[1,0,1,1,1]这种数组,如下图)

    这时候你如果还要让left自增,就会错过答案了,所以必须要让right自减

代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值