LeetCode第153题:寻找旋转排序数组中的最小值

349 阅读2分钟

题干

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到: 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2] 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7] 注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]]

给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。

示例 1:

输入:nums = [3,4,5,1,2]
输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。

解法1:一次循环

直接遍历,当下一个值小于我们当前的值时下一个值就是我们即将要找到值

执行用时:88 ms, 在所有 JavaScript 提交中击败了48.68%的用户

内存消耗:37.7 MB, 在所有 JavaScript 提交中击败了93.38%的用户

代码实现

  var findMin = function (nums) {
    let length = nums.length
    for (let i = 0; i < length; i++) {
      if (nums[i] > nums[i + 1]) {
        return nums[i + 1]
      }
    }
    return nums[0]
  };

解法2:二分

只要认清一个道理:最右边的数总是小于左区间的数,最左边的数总是大于右区间的数

那么当我们二分查找时,当前的mid值如果大于max值的时候,说明当前mid在左区间,则min=mid+1;相反如果我们的mid小于我们的max值时,说明我们当前的位置正处于右区间,所以我们要使max=mid,因为我们要找的值是右区间的开始值,以此类推。最后我们的min最终会停留在最小值上。

代码实现

执行用时:80 ms, 在所有 JavaScript 提交中击败了83.82%的用户

内存消耗:38.6 MB, 在所有 JavaScript 提交中击败了23.98%的用户

 var findMin = function (nums) {
    let low = 0;
    let max = nums.length - 1;
    while (low < max) {
      let  mid = Math.floor((max + low) / 2)
        if (nums[mid] > nums[max]) {
            low = mid + 1
        } else {
            max = mid
        }
    }
    return nums[low]
};