题目
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
解题
用两个指针,一个指向第一个,一个指向最后一个,中间的数字大于第一个就让第一个的指针指到中间的数字(这个时候数组就剩一半了),中间的小于最后一个就让最后一个指向中间的数字。最小的数字肯定是中间那个数字的下一个,最后两个指针是挨着的一个指向中间的数字,一个指向下一个,返回指向下一个的就可以了。要是数组是顺序的就直接返回第一个指针指向的数字。要是三个指针指向的数字相等就按照顺序排序的方法找到最小值。
代码
public class T11 {
public static void main(String[] args) throws Exception {
int[] nums={3,4,5,1,2};
System.out.println(findMin(nums,5));
int[] nums1={1,2,3,4,5};
System.out.println(findMin(nums1,5));
}
public static int findMin(int nums[],int length) throws Exception {
//数组为空
if (nums == null || nums.length < 0) {
throw new Exception("空数组");
}
int left = 0;
int right = length - 1;
int indexMid = left;//如果是顺序数组,则直接返回第一个即可
while (nums[left] >= nums[right]) {
if (right - left == 1) {
indexMid = right;
break;
}
indexMid = (left + right) / 2;
//如果数组特殊,left,right,indexMid指向的数字都相等,就用顺序查找
if (nums[left] == nums[right] && nums[indexMid] == nums[left])
return MinInOrder(nums, left, right);
//较为常见的数组,则用类似二分查找的思路
if (nums[left] <= nums[indexMid])
left = indexMid;
if (nums[right] >= nums[indexMid])
right = indexMid;
}
return nums[indexMid];
}
private static int MinInOrder(int[] nums, int left, int right) {
int result = nums[left];
for(int i = left+1;i<=right;i++){
if(result>nums[i])
result = nums[i];
}
return result;
}
}