把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
//异常判断
if(array.length == 0){
return 0;
}
int left = 0;
int right = array.length - 1;
int mid = left;
while(array[left] >= array[right]){
//数组中只有两个元素
if(right - left == 1){
mid = right;
break;
}
}
//数组中有多个元素
// mid = (left + right)/2;
mid = (left + right) / 2;
//如果数组中所有的数全相等
if(array[left] == array[mid] && array[left] == array[right]){
return orderFind(array,left,right);
}
//如果最左边小于等于中间,说明最小值在后半部分,把mid位置标记为最左侧如{3,4,5,1,2}
if(array[left] <= array[mid]){
left = mid;
}
//如果最左边的数大于等于中间,说明最小值在前半部分,把mid位置标记为最右侧{4,5,1,2,3}
else if(array[left] >= array[mid]){
right = mid;
}
return array[mid];
}
public int orderFind(int[] array,int left,int right){
int min = array[left];
for(int i = left + 1;i <= right;i++){
if(array[i] < array[left]){
min = array[i];
}
}
return min;
}
}
应该来说,这是考虑最周全的一种写法,但是我们在实际运行过程中编译器给出这样的提示:您的代码已保存
运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。
case通过率为0.00%
下面我们进行相应的优化 答案来源是剑指offer(java版).pdf
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array==null){
return 0;
}
int leftIndex=0;
int rightIndex=array.length-1;
int mid=0;
while(array[leftIndex]>=array[rightIndex]){
if(rightIndex-leftIndex<=1){
mid=rightIndex;
break;
}
mid=(leftIndex+rightIndex)/2;
if(array[leftIndex]==array[rightIndex]&&array[leftIndex]==array[mid]){
if(array[leftIndex+1]!=array[rightIndex-1]){
mid=array[leftIndex+1]<array[rightIndex-1]?(leftIndex+1):(rightIndex-1);
break;
}else{
leftIndex++;
rightIndex--;
}
}else{
if(array[mid]>=array[leftIndex])
leftIndex=mid;
else {
if(array[mid]<=array[rightIndex])
rightIndex=mid;
}
}
}
return array[mid];
}
}
显然这里我们进行了一定的优化,这是这题我们其实还有其他的优化,如果知识纯粹的求得数组里面的最小值,假定第一个数组是最小值,当然我们可以直接使用一个for循环进行遍历直接交换即可得到我们想要的结果,二期居然能够通过,但我觉得这种方法肯定不是出题者的意图,毕竟太简单了!!!