【题目】把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减序列的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
【思路】①正常情况下可利用二分法进行查找;
②特殊情况,要用顺序查找。
1 package com.exe2.offer; 2 3 /** 4 * 【题目】输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。 5 * 【思路】:①正常情况下可利用二分法进行查找; 6 * ②特殊情况,要用顺序查找。 7 * @author WGS 8 * 9 */ 10 public class SearchMinNumInSpinArray { 11 public int getMinNum(int[] arrs){ 12 if(arrs==null||arrs.length<=0){ 13 try { 14 throw new Exception("Invalid arrays"); 15 } catch (Exception e) { 16 // TODO Auto-generated catch block 17 e.printStackTrace(); 18 } 19 } 20 //定义指针 21 int preIndex=0; 22 int endIndex=arrs.length-1; 23 int midIndex=preIndex;//此处不宜直接设为0,因为当判断到要求将数组前0个元素旋转时,第一个元素 即为最小值(不一定是0) 24 25 //默认是递增的排序 26 while(arrs[preIndex]>=arrs[endIndex]){ 27 28 //二分法 29 midIndex=(preIndex+endIndex)/2; 30 31 //若出现前后中指针所指数组皆相同时则无法使用二分法,要用顺序查找法 32 if(arrs[preIndex]==arrs[endIndex]&&arrs[midIndex]==arrs[endIndex]){ 33 return minInOrder(arrs,preIndex,endIndex); 34 } 35 36 37 if(arrs[midIndex]>=arrs[preIndex]){ 38 preIndex=midIndex; 39 }else if(arrs[midIndex]<=arrs[preIndex]){ 40 endIndex=midIndex; 41 } 42 //判断下是否前后指针相遇,相遇后指针所指即为最小值 43 if(endIndex-preIndex==1){ 44 midIndex=endIndex; 45 break; 46 } 47 48 49 50 } 51 return arrs[midIndex]; 52 53 } 54 //顺序查找法 55 public int minInOrder(int[] arrs,int preIndex,int endIndex){ 56 int result=arrs[preIndex]; 57 for(int i=preIndex+1;i<=endIndex;i++){ 58 if(result>arrs[i]){ 59 result=arrs[i]; 60 } 61 } 62 63 return result; 64 65 } 66 public static void main(String[] args) { 67 // TODO Auto-generated method stub 68 69 /** 70 * 当数组是3,2,3,3,3时查找到的最小值是3 不对 因为中间值是3 无法判断,要使用顺序查找 71 */ 72 int[] arrs=new int[]{1,0,1,1,1};//新建一个旋转后的数组3,4,5,1,2 73 SearchMinNumInSpinArray s=new SearchMinNumInSpinArray(); 74 int min=s.getMinNum(arrs); 75 System.out.println("最小值是"+min); 76 77 } 78 79 }