题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
示例 1:
输入:[3,4,5,1,2]
输出:1
示例 2:
输入:[2,2,2,0,1]
输出:0
思路:我们发现旋转后的数组可以划分为两个排序的子数组,并且前边子数组的元素全部大于等于后边子数组的元素,并且刚好最小的元素就是这两个子数组的分界线,而我们的目的就找到和这个分界线,所以我们可以用二分查找!
解答:
public int findMin(int[] nums){
if (nums==null ||nums.length==0)
return -1;
int len=nums.length;
int left=0;
int right=len-1;
int index=left;//防止一个排好的数组
while (nums[left]>=nums[right]){
if(right-left==1)
return nums[right];
index=(left+right)/2;
//让他俩不断的忘中间靠
if (nums[index]>=nums[left]){//在左边递增数组里
left=index;
}else if(nums[index]<=nums[right]){//在右边递增数组里
right=index;
}
}
return nums[right];
}
以上的方法在LeetCode上提交会超时!并且没有考虑极端的情况!
假设我么你的数组是{0 1 1 1 1} 的旋转数组{1 0 1 1 1 }或者{1 1 1 0 1},在这两个数组中 ,他们的第一个数组和最后一个数字还有中间的数组 都是数字1,那程序在执行判断时就不知道中间的数字1 是前边的数组还是后边的数组了,所以在这种情况下 我们只能顺序查找!
所以正确的代码应该是酱:
public int findMin(int[] nums){
if (nums==null ||nums.length==0)
return -1;
int len=nums.length;
int left=0;
int right=len-1;
int index=left;//防止一个排好的数组
while (nums[left]>=nums[right]){
//如果找到分界线了
if(right-left==1)
index=right;
index=(left+right)/2;
//如果都一样无法判断的话 只能顺序查找了!
if (nums[left]==nums[right]&&nums[right]==nums[index]){
int result=nums[left];
for (int i = left+1; i <=right; i++) {
if (result>nums[i])
result=nums[i];
}
}
//让他俩不断的忘中间靠
if (nums[index]>=nums[left]){//在左边递增数组里
left=index;
}else if(nums[index]<=nums[right]){//在右边递增数组里
right=index;
}
}
return nums[right];
}
okok 就这样,今天好困好困~~睡了睡了···
本文探讨了如何优化解决旋转数组中最小元素的问题,避免了传统二分查找的效率瓶颈,通过实例和正确代码实现,重点讲解了在特殊情况下如何进行顺序查找。
329

被折叠的 条评论
为什么被折叠?



