剑指Offer(第二版)面试题11:旋转数组的最小数字

来源:互联网 发布:联合国贸发会议数据库 编辑:程序博客网 时间:2024/06/04 20:34


(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/71938734冷血之心的博客)


剑指Offer面试题11:旋转数组的最小数字

题目一:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组{3,4,5,1,2}是数组{1,2,3,4,5}的一个旋转,该数组的最小值为1



思路1:暴力遍历法:

/** * 方法1:暴力遍历数组,时间复杂度为O(n),指定不行,没有利用到数组有序的特性 * @param arr * @return */public int getMin(int[] arr){int min = arr[0];for (int i = 1; i < arr.length; i++) {if(min>arr[i])min = arr[i];}return min;}

思路2:利用旋转数组部分有序的特点,进行二分查找,减小时间复杂度。注意特殊情况的处理。


/** * 利用二分查找的思想,时间复杂度为O(logn)。 * 注意对特殊情况的处理 * @param arr * @return */public int getMin2(int[] arr){int index1 = 0;int index2 = arr.length-1;int mid = 0; while(arr[index1]>=arr[index2]){if(index2-index1==1){ // 两个指针已经相邻mid = index2;break;}mid = (index1+index2)/2;// 如果下标为index1和index2以及mid指向的三个数字都相等,则只能顺序查找if(arr[index1]==arr[index2]&&arr[mid]==arr[index1]){return inInOrder(arr,index1,index2);}if(arr[mid]>=arr[index1]){index1 = mid;}else if(arr[mid]<=arr[index2]){index2 = mid;}}return arr[mid];}public static int inInOrder(int[] arr, int index1, int index2) {int min = arr[index1];for(int i = index1+1;i<=index2;i++){if(min>arr[i])min = arr[i];}return min;}
在上面的算法中,当前面的若干个元素是指0个元素旋转到后边时,mid=0,则不会进入while循环,直接返回arr[0],即是数组中的最小值。

反之进行二分查找,根据条件变化左右指针,直到两个指针相邻。

特殊情况:前、后以及mid指针所指向的数均相同,则不能判断该如何移动前后指针,此时,必须在前后指针范围内使用顺序查找来搞定。




如果对你有帮助,记得点赞哦~欢迎大家关注我的博客,可以进群366533258一起交流学习哦~





2 0
原创粉丝点击