【剑指offer】旋转数组的最小数字

题目链接:旋转数组的最小数字

 

题意:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

 

题解:很容易想到的是o(n)的算法。但是不能忽略它旋转数组的性质。数组划分成两段,且都是有序的。可以优化到o(logn)

设中间的数为mid,最左边的数为left,最右边的数为right,很容易得到三种情况,设最小的数为numer.

  • array[mid] < array[right]    此时numer在[left,mid],right = mid
  • array[mid] > array[right]        此时number在[mid+1,right],left = mid+1
  • array[mid] = array[right]   此时不能确定是否在有序范围内,所以只能顺序查找,让right-1

因为二分的范围会到只剩下两个的情况,而我们只是在用mid和right做比较。所以在第一种情况不能直接right=mid-1.

 

代码:

 1 O(n)
 2 import java.util.ArrayList;
 3 public class Solution {
 4     public int minNumberInRotateArray(int [] array) {
 5         int len = array.length;
 6         if(len == 0){
 7             return 0;
 8         }
 9         else{         
10             int num = array[0];
11             for(int i = 0 ;i < len;i++){
12                 if(num > array[i]){
13                     num = array[i];
14                 }
15             }       
16             return num;
17         }
18     }
19 }
20 
21 
22 OR
23 
24 O(logn)
25 import java.util.ArrayList;
26 public class Solution {
27     public int minNumberInRotateArray(int [] array) {
28         int len = array.length;
29         if(len == 0){
30             return 0;
31         }
32         else{
33             int left = 0;
34             int right = len-1;
35             int mid,num;
36             
37             while(left < right){
38                 mid = (left + right)/2;
39                 if( array[mid] < array[right]){
40                     right = mid;
41                 }
42                 else if(array[mid] > array[right]){
43                     left = mid+1;
44                 }
45                 else{
46                     right--;
47                 }
48             }
49             num = array[left];
50             
51             return num;
52         }
53     }
54 }

 

posted @ 2019-03-03 15:11  甜酒果。  阅读(115)  评论(0编辑  收藏  举报