难度:简单

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

    示例:

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

    解题思路:

    1. var minArray = function(numbers) {
    2. let min = numbers[0];
    3. for(let i of numbers){
    4. min = Math.min(i, min)
    5. }
    6. return min
    7. };

    旋转后的数组可以划分为两个有序的子区间,前面区间的元素都大于等于后面的元素,我们要找的就是两个子区间的分界
    很自然想到二分查找
    nums[mid] > nums[right]

    最小元素肯定在mid的右边,所以 left = mid + 1
    nums[mid] == nums[right]

    此时 mid 可能处于左边的增区间,也可能处于右边的增区间,即最小元素不确定在它的左边还是右边
    所以 right— ,换一个 nums[right] 再试
    nums[mid] < nums[right]

    此时 mid 肯定处在右边的增区间,所以 right = mid

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