有序数组a经过一次旋转处理,也可能没有旋转,且a中肯能存在重复的数字。例如有序数组[1,2,3,4,5,6]可以旋转处理成[4,5,6,1,2,3];特例一,[1,2,3,4,4,4,4,4,4]旋转成[4,4,4,4,4,1,2,3,4];特例二,[1,2,3,4,4,4,4,4,4]旋转成[4,1,2,3,4,4,4,4,4];特例三,[1,1,1,1,1,2,3]旋转成[1,2,3,1,1,1,1]。
package com.lancq.array;
/**
* @Author lancq
* @Description
* @Date 2018/11/4
**/
public class ArrayTest {
public static void main(String[] args) {
int[] a = new int[]{4, 5, 6, 2, 3};
int[] a2 = new int[]{6, 7, 3, 4, 5};
int[] a3 = new int[]{4, 0, 1, 2, 3};
int[] a4 = new int[]{-1, 0, 1, 2, 3};
int[] a5 = new int[]{4,4,4,4,4,1,2,3,4};
int[] a6 = new int[]{4,1,2,3,4,4,4,4,4};
int[] a7 = new int[]{1,2,3,1,1,1,1};
System.out.println("递归查找旋转数组中的最小值:");
System.out.println(findMinInRotatedArray(a,0, a.length-1));
System.out.println(findMinInRotatedArray(a2,0, a2.length-1));
System.out.println(findMinInRotatedArray(a3,0, a3.length-1));
System.out.println(findMinInRotatedArray(a4,0, a4.length-1));
System.out.println(findMinInRotatedArray(a5,0, a5.length-1));
System.out.println(findMinInRotatedArray(a6,0, a6.length-1));
System.out.println(findMinInRotatedArray(a7,0, a7.length-1));
System.out.println("非递归查找旋转数组中的最小值:");
System.out.println(findMinInRotatedArray2(a));
System.out.println(findMinInRotatedArray2(a2));
System.out.println(findMinInRotatedArray2(a3));
System.out.println(findMinInRotatedArray2(a4));
System.out.println(findMinInRotatedArray2(a5));
System.out.println(findMinInRotatedArray2(a6));
System.out.println(findMinInRotatedArray2(a7));
}
/**
* 递归:查找旋转数组中的最小值
* 有序数组a经过一次旋转处理,也可能没有旋转,且a中肯能存在重复的数字。
* 例如有序数组[1,2,3,4,5,6]可以旋转处理成[4,5,6,1,2,3];
* 特例一,[1,2,3,4,4,4,4,4,4]旋转成[4,4,4,4,4,1,2,3,4];
* 特例二,[1,2,3,4,4,4,4,4,4]旋转成[4,1,2,3,4,4,4,4,4];
* 特例三,[1,1,1,1,1,2,3]旋转成[1,2,3,1,1,1,1]
* @param a
* @param left
* @param right
* @return
*/
public static int findMinInRotatedArray(int[] a, int left, int right){
//递归退出条件
if(left == right || a[left] < a[right]){
return a[left];
}
int mid = left + (right - left)/2;
if(a[left] > a[mid]){
return findMinInRotatedArray(a, left, mid);
} else if(a[left] < a[mid]){
return findMinInRotatedArray(a, mid+1, right);
} else {
return Math.min(findMinInRotatedArray(a, left, mid), findMinInRotatedArray(a, mid+1, right));
}
}
/**
* 非递归:查找旋转数组中的最小值
* 有序数组a经过一次旋转处理,也可能没有旋转,且a中肯能存在重复的数字。
* 例如有序数组[1,2,3,4,5,6]可以旋转处理成[4,5,6,1,2,3];
* 特例一,[1,2,3,4,4,4,4,4,4]旋转成[4,4,4,4,4,1,2,3,4];
* 特例二,[1,2,3,4,4,4,4,4,4]旋转成[4,1,2,3,4,4,4,4,4];
* 特例三,[1,1,1,1,1,2,3]旋转成[1,2,3,1,1,1,1]
* @param a
* @return
*/
public static int findMinInRotatedArray2(int[] a){
int low = 0;
int high = a.length -1;
int mid = 0;
while (low < high){
//循环退出条件
if(low == high -1){
break;
}
//说明数组在 a[low] 至 a[high] 上没有旋转
if(a[low] < a[high]){
return a[low];
}
mid = (low + high) / 2;
//说明最小值在a[low] 至 a[mid]之间
if(a[low] > a[mid]){
high = mid;
continue;
}
//说明最小值在a[mid] 至 a[high]之间
if(a[mid] > a[high]){
low = mid + 1;
continue;
}
//特殊情况 a[low]==a[mid]==a[high]
while(low < mid){
if(a[low] == a[mid]){//特例一
low++;
} else if(a[low] < a[mid]){//特例二
return a[low];
} else {
high = mid;
break;
}
}
}
return Math.min(a[low],a[high]);
}
}