Description
Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become:
- [4,5,6,7,0,1,2] if it was rotated 4 times.
- [0,1,2,4,5,6,7] if it was rotated 7 times.
Notice that rotating an array [a[0], a[1], a[2], …, a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], …, a[n-2]].
Given the sorted rotated array nums of unique elements, return the minimum element of this array.
You must write an algorithm that runs in O(log n) time.
Examples
Example 1:
Input: nums = [3,4,5,1,2] Output: 1 Explanation: The original array was [1,2,3,4,5] rotated 3 times.
Example 2:
Input: nums = [4,5,6,7,0,1,2] Output: 0 Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.
Example 3:
Input: nums = [11,13,15,17] Output: 11 Explanation: The original array was [11,13,15,17] and it was rotated 4 times.
Constraints:
n == nums.length 1 <= n <= 5000 -5000 <= nums[i] <= 5000 All the integers of nums are unique. nums is sorted and rotated between 1 and n times.
思路
这题是想要找出循环升序链表里面最小的那个数字,题目也说了要用O(log n)的时间复杂度,所以肯定是用二分法 所以问题的关键就在于怎么设定二分规则 这里的二分规则就是要明确再给出一个循环升序链表的时候,那个最小值会位于什么地方 这里以最小值在middle左侧为例
- 首先第一种也是最好找的,就是nums[start] < nums[end]
因为是循环升序,所以当循环起来的时候,必然有nums[start] > nums[end],而当不满足这个条件的时候,就是他没有循环,只是升序排列的情况,那最小值必然在左侧,甚至就是nums[start] - 第二种是nums[middle] < nums[start]
在普通升序情况下,nums[start] < nums[middle]是正常情况,当不满足这个条件的时候,意味着循环发生在左侧的环境内,也就是最小值在左侧产生
那么这两种情况以外的其他情况,就是最小值在右侧的情况啦
代码
class Solution {
public int min(int[] nums, int start, int end){
if(start == end)
return nums[start];
int mid = (start + end) / 2;
if(nums[start] < nums[end] || nums[start] > nums[mid])
return min(nums, start, mid);
else
return min(nums, mid + 1, end);
}
public int findMin(int[] nums) {
int len = nums.length - 1;
return min(nums, 0, len);
}
}
|