剑指offer06-旋转数组的最小值
一、 题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
题目分析:
例如: 1 2 3 4 5 6 7 -->它的旋转数组为4 5 6 7 | 1 2 3,最小值为1
0 1 1 1 1 -->它的旋转数组为1 1 | 0 1 1 ,最小值为0
解题思路: 数组部分有序(前部分递增,后部分也递增),此问题即求后部分数组的开头元素的值,即是整个数组的最小值。
注意:将开头的若干个元素移到末尾,这个若干个也可以是
二、解题方法
2.1 暴力法
此方法不管数组的部分有序性,直接遍历数组。时间复杂度为O(n).
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
//暴力法
int len = array.length;
if(len==0)
return 0;
int min = array[0];
for(int i=0;i<len;i++){
if(array[i]<min)
min = array[i];
}
return min;
}
}
2.2 解法二
参考:link ,不太好理解
import java.util.ArrayList;
/**
三种情况:
1)将数组开头的0个元素移到了末尾,即还是原数组
2)mid可以与low和high位置比较大小
3)mid和low和high位置的元素大小相等
*/
public class Solution {
public int minNumberInRotateArray(int [] array) {
int len = array.length;
if(len == 0)return 0;
int low=0, high=len-1;
if(array[0] < array[len-1]){return array[0];}//数组本身
while(low<high){
int mid = (high+low)/2;
if((array[mid] == array[low])&&(array[mid]==array[high]))
return directQuery(array);
if(array[mid] <= array[high]){high = mid;}
else if(array[mid]>= array[low]) {low = mid;}
if(low+1==high)return array[high];
}
return -1;
}
public int directQuery(int [] array){//顺序查找
int min = array[0];
for(int num:array){
if(num<min) min = num;
}
return min;
}
}
2.3 解法三(思想比较好理解,比较简单)
和右端点比较
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
int len = array.length;
if(len == 0)return 0;
int low = 0, high = len-1;
if(array[0]<array[len-1])return array[0];//是原数组,没有移动过
while(low < high){
int mid = (low+high)/2;
if(array[mid] > array[high]){
//表明min肯定在[mid+1,high]之间
low = mid + 1;
}else if (array[mid] < array[high]){
//表明min肯定在[low,mid]之间
high = mid;
}else {
high--;
}
}
return array[high];
}
}
和左端点比较
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
int len = array.length;
if(len == 0)return 0;
int low = 0, high = len-1;
//if(array[0]<array[len-1])return array[0];//是原数组,没有移动过
while(low < high){
int mid = (low+high)/2;
if(array[mid] > array[low]){
//表明min肯定在[mid+1,high]之间
low = mid ;
}else if (array[mid] < array[low]){
//表明min肯定在[low,mid]之间
high = mid;
}else {
low++;
}
}
return array[low];
}
}