Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).
Find the minimum element.
You may assume no duplicate exists in the array.
先审题,理清思路,该题是将一个已排序的数组,从某个位置折断,重新拼接成一个新数组,根据题意会出现几种情况:
1.原数组未改变(折断位置为0)
2.数组被分成两段,两段分别以升序排列,前一段中元素比后一段元素大
那我们就可以遍历数组元素,与前一元素比较,如果当前元素比前一元素大,继续遍历,如果当前元素比前一元素小,说明当前元素为原数组第一个元素(即最小元素),如果遍历完整个数组,仍然未能找到当前元素比前一元素小,则为情况1,这时返回数组第一个元素。
代码如下:
public int findMin(int[] nums) {
int i = 1;
while( i < nums.length ){
int pre = nums[i - 1];
int cur = nums[i];
if(cur > pre){
i++;
}else if(cur < pre)
return cur;
}
return nums[0];
}
该算法时间复杂度为O(n)
参考其他更高效的算法,采用二分法查找,代码如下:
public static int findMin(int[] nums) {
int l = 0 , r = nums.length - 1;
while( r - l > 1){
int mid = (r + l) /2;
if(nums[l] < nums[mid] && nums[mid] > nums[r])
l = mid;
else
r = mid;
}
return Math.min(nums[l], nums[r]);
}
条件1.nums[l]和nums[mid]处于前一段递增数列,nums[r]处于后一段递增数列,此时将l 值改为mid
2.nums[mid]和nums[r]同处于后一段递增数列,或者原数组未变化则将r 的值改为mid
6 7 8 9 1 2 3 4 5
l mid r 条件2
l mid r 条件1
l mid r 条件1
l r
该算法复杂度为O(logn)