08 JavaScript旋转数组的最小数字 牛客网JZ11

需求:

        有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

数据范围:100001≤n≤10000,数组中任意元素的值: 0≤val≤10000

要求:空间复杂度:O(1) ,时间复杂度:O(logn)

输入:[3,4,5,1,2]

返回值:1

输入:[3,100,200,3]

返值:3

实现:

        刚看到题的时候,我寻思这是啥玩意?脑子也很乱,今天重新捋顺,算是过了提交,如果逻辑上有些问题还请各位大佬批评指正。

旋转数组的特性:

①包含两个有序序列;

②最小数一定位于第二个序列的开头;

③前序列的值都>=后序列的值

 二 分 法 

1.定义 l 和 r 两个指针分别指向数组rotateArray[0](第一序列的开头)和rotateArray[rotateArray.length-1](第二序列的结尾);

2.判断该数组是否为旋转数列:rotateArray[l]>=rotateArray[r],由于默认的例子有不符合旋转数组的情况,所以单列一份首尾的判断rotateArray[l]<rotateArray[r]

3.循环二分: 设 m =Math.floor((r+l)/2) 为每次二分的中点,判断m的位置。

m大于l,则m位于前面的递增子数组,此时最小元素位于m的后面。我们可以让l指向m。移动之后,l仍然位于前面的递增数组中。

m小于r,则m位于后面的递增子数组,此时最小元素位于m的前面。我们可以让r指向m。移动之后,r仍然位于后面的递增数组中。

当 l 和 r 相邻时,最小值为rotateArray[r],循环结束。

4. 当[1,1,1,4,1,1,1,1,1]这种情况出现时,我们没法确定m的位置,定义一个方法Min()来确定最小值。

function minNumberInRotateArray(rotateArray) {
  let l = 0;
  let r = rotateArray.length - 1;
  let m = 0;
  //     先判断首尾
  if (rotateArray[l] < rotateArray[r]) {
    return rotateArray[l];
  }
  //     确定是旋转数组
  while (rotateArray[l] >= rotateArray[r]) {
    if (r - l === 1) {
      break;
    }
    //         判断m是在前半段还是后半段
    m = Math.floor((l + r) / 2);
    if (rotateArray[l] == rotateArray[m] || rotateArray[r] == rotateArray[m]) {
      return Min(rotateArray);
    }
    //      前
    if (rotateArray[l] < rotateArray[m]) {
      l = m;
    }
    //      后
    else if (rotateArray[r] > rotateArray[m]) {
      r = m;
    }
  }
  return rotateArray[r];
}
function Min(arr) {
  let min = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < min) {
      min = arr[i];
    }
  }
  return min;
}
module.exports = {
  minNumberInRotateArray: minNumberInRotateArray,
};

 直 接 遍 历 法 

function minNumberInRotateArray(rotateArray)
{
    // write code here
    // 数组从左向右查
    for(var i=0; i<rotateArray.length-1;i++){
        // 如果,前一个 > 后一个,则后一个为最小元素
        if(rotateArray[i+1]<rotateArray[i])
            return rotateArray[i+1];
    }
    // 如果到数组末尾,依然没有前一个 > 后一个出现,则第一个为最小元素。
    return rotateArray[0];
}
module.exports = {
    minNumberInRotateArray : minNumberInRotateArray
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值