# 剑指 Offer 11. 旋转数组的最小数字

# 题目

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

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

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

# 思路

旋转数组其实由两个有序数组拼接而成,可以使用二分法,只需要找到拼接点就可以了。

  1. arr[mid] > arr[high] 出现这种情况的array类似[3,4,5,6,0,1,2],此时最小数字一定在mid的右边。 low = mid + 1

  2. array[mid] == array[high] 出现这种情况的array类似 [1,0,1,1,1]或者[1,1,1,0,1],此时最小数字不好判断在mid左边 还是右边,这时只好一个一个试 。high = high - 1

  3. array[mid] < array[high] 出现这种情况的array类似[6,7,0,1,2,4,5],此时最小数字一定就是array[mid]或者在mid的左边。因为右边必然都是递增的。high = mid

# 解答

const minArray = (nums) => {
  let left = 0;
  let right = nums.length - 1;
  while (left < right) {
    const mid = left + right >>> 1;
    if (nums[mid] > nums[right]) {
      left = mid + 1;
    } else if (nums[mid] == nums[right]) {
      right--;
    } else {
      right = mid;
    }
  }
  return nums[left];
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15