剑指 Offer丨 11. 旋转数组的最小数字(JavaScript版本)

题目: 旋转数组的最小数字

  • 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
  • 给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。
  • 注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
  • 提示:
    • n == numbers.length
    • 1 <= n <= 5000
    • -5000 <= numbers[i] <= 5000
    • numbers 原来是一个升序排序的数组,并进行了 1 至 n 次旋转

题解一:管他三七二十一,求最小值

  • 思路:看不懂题目。。不就是求最小值。上来就求最小值(可行!)但辜负出题人的好意(考点)。据说这还是字节面试题,你总不可能直接说求最小值吧。。。
  • 代码:
/**
 * @param {number[]} numbers
 * @return {number}
 */
var minArray = function(numbers) {
    numbers.sort((a,b)=>a-b);
    return numbers[0];
};

题解二:暴力突破

  • 思路:
    • 数组是递增数组(前提)
    • 发现旋转数组在旋转后,有个分界点,而这个分界点就是最小的那个数
    • 利用遍历找到分界点(即是突然变小的值)
  • 代码:
/**
 * @param {number[]} numbers
 * @return {number}
 */
var minArray = function(numbers) {
  for(let i=0;i<numbers.length;i++){
      if(numbers[i]>numbers[i+1]){
          return numbers[i+1];
      }
  }
  return numbers[0];
};
  • 复杂度分析:
    • 时间复杂度:O(n)
    • 空间复杂度: O(n)

题解三:二分法(推荐)

  • 思路:二分法注意边界

    • 形成思路模式:有序->想到二分法
    • 1首先,创建两个指针 left, right 分别指向 numbers首尾数字,然后计算出两指针之间的中间索引值 mid,然后我们会遇到以下三种情况:
    • mid > right :代表最小值一定在 mid 右侧,所以 left移到 mid + 1的位置。
    • mid< right :代表最小值一定在 mid 左侧或者就是 mid,所以 right 移到 mid的位置。
    • mid既不大于 left 指针的值,也不小于 right指针的值,代表着 mid 可能等于 left指针的值,或者 right 指针的值,我们这时候只能让 right 指针递减
    • 最后返回 Math.min(numbers[left],numbers[right])
  • 代码:

/**
 * @param {number[]} numbers
 * @return {number}
 */
var minArray = function(numbers) {
  let left= 0;
  let right = numbers.length-1;
  while(right-left>1){
      let mid = left+((right-left)>>1);
      if(numbers[mid]>numbers[right]){
          left = mid+1;
      }
      else if(numbers[mid]<numbers[right]){
          right = mid;
      }
      else{
          right--;
      }
  }
  return Math.min(numbers[left],numbers[right]);
};
  • 复杂度分析:
    • 时间复杂度:O(logn)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值