题目描述:
已知一个长度为 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.如果数组长度为1,则返回唯一的一个数
2.定义两个指针,第一个left指向数组开头,第二个right指向数组结尾
3.检查数组是否被反转,如果没有,则返回数组里的第一个数
4.while循环,当left小于right时,取中间作为mid进行二分搜索
如果mid的左边一个数大于mid,则返回nums[mid+1]
如果mid的右边一个数小于mid,则返回nums[mid]
5.否则的话,如果left所在的数小于mid,则将left右移至mid+1的位置(砍掉左半边)
6.否则的话,将right左移至mid-1的位置(砍掉右半边)
Java:
public int findMin(int[] nums) { if(nums.length == 1) { return nums[0]; } int left = 0; int right = nums.length - 1; if(nums[right] > nums[0]) { return nums[0]; } while(left < right) { int mid = left + (right - left) / 2; if(nums[mid] > nums[mid+1]) { return nums[mid+1]; } else if(nums[mid-1] > nums[mid]) { return nums[mid]; } else if(nums[mid] > nums[left]) { left = mid + 1; } else { right = mid - 1; } } return nums[left]; }
JavaScript:
var findMin = function(nums) { if(nums.length === 1) { return nums[0]; } let left = 0; let right = nums.length - 1; if(nums[right] > nums[0]) { return nums[0]; } while(left < right) { let mid = Math.floor(left + (right - left) / 2); if(nums[mid] > nums[mid+1]) { return nums[mid+1]; } else if(nums[mid-1] > nums[mid]) { return nums[mid]; } else if(nums[mid] > nums[left]) { left = mid + 1; } else { right = mid - 1; } } };