旋转数组的最小数字

来源:互联网 发布:淘宝双11营业额 编辑:程序博客网 时间:2024/06/10 01:52

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

分析这个题目,其实不用看什么数组的旋转的描述,感觉上没有多少意义,实际要做的就是对这个数组{3,4,5,1,2}进行操作,找到最小的那个数,当然这里自然而然的互相到如果数组中有相同的元素时应该在怎么办。稍后分析。
现在来分析数组中的元素没有重复元素时,第一想到的肯定是进行数组的遍历,找出最小的数,但是这没有意义。我们再考虑这个数组其实是两个有序数组的结合。若要在有序数组中查找某个元素,一般采用二分查找。
而二分查找要满足以下条件:
(1)必须采用顺序存储结构
(2)必须按关键字大小有序排列
他的原理是将数组分为三部分,依次是中值(所谓的中值就是数组中间位置的那个值)前,中值,中值后;将要查找的值和数组的中值进行比较,若小于中值则在中值前 面找,若大于中值则在中值后面找,等于中值时直接返回。然后依次是一个递归过程,将前半部分或者后半部分继续分解为三部分。

二分查找一般是要输入(作为参数)一个查找的值去匹配,而本题中,这个值是不定的,是需要寻找的,也就是数组的最小值。
我们首先把left指向数组的开头,而right指向数组的结尾,数组中包含两个非降序数组,有以下几种情况:
(1)array[mid] > array[hight];这个时候,那么array[mid]一定在前一个升序的子数组。最小的数一定在后面的数组中,所以将left指向mid+1。
(2)array[mid] == array[hight].这个时候就要思考清楚了,加入有数组{1,1,1,1,1,0,1};原题中规定数组非降序,就只有升序和相等情况,相等的情况,不符合二分查找的要求,就要一个个的遍历数组进行求解,也就是将right每次都减小1;
(3)array[mid] < array[hight],这个时候最小的数,一定在前面的数组中。
综上分析,代码如下:

public class Solution {    public int minNumberInRotateArray(int [] array) {       if(array.length == 0){           return 0;       }else{           int left = 0;           int right = array.length - 1;           while(left < right){               int mid = left + (right - left)/2;               if(array[mid] > array[right]){                   left = mid + 1;               }else if(array[mid] == array[right]){                   right -= 1;               }else{                   right = mid;               }           }           return array[left];       }    }}
0 0
原创粉丝点击