Fork me on GitHub

【Offer】[11] 【旋转数组的最小元素】

题目描述

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

思路分析

  • 利用二叉查找的思路,由于是旋转数组,可以分成两个排序的子数组,而且最小元素是这两个数组的分界线,设置两个索引指针分别指向首尾元素,判断它们与数组中间元素的大小关系:

    • 如果中间元素>=第一个元素则说明要找的最小元素在中间元素的后面,将第一个指针指向中间元素;
    • 如果中间元素<=最后一个元素则说明要找的最小元素在中间元素的前面,将第二个指针指向中间元素;
    • 这样重复的缩小范围查找,最终第一个指针会指向前面子数组的最后一个元素,而第二个指针会指向后面子数组的第一个元素,即两个指针会相邻,这是最小元素便为第二个指针所指的元素
  • 特殊情况: 如果中间元素 、第一个指针指向元素 、第二个指针指向元素 都相等,这时就不能用二分查找的思路,可以用顺序查找思路进行查找最小值

Java代码

public class Offer011 {
    public static void main(String[] args) {
//      int [] arr = {3,4,5,1,2};
        int [] arr = {1,0,1,1,1};
        int minNumberInRotateArray = minNumberInRotateArray(arr);
        System.out.println(minNumberInRotateArray);
        
    }
    
    public  static int minNumberInRotateArray(int [] array) {
        return Solution1(array);
    }
    
    /**
     * 利用二分查找的思路,注意:要考虑特殊情况
     * @param array
     * @return
     */
    public static  int Solution1(int [] array) {
        
        int index1 = 0;
        int index2 = array.length-1;
        int indexMid = index1;
        while(array[index1]>=array[index2]) {
            if(index2-index1==1) {
                indexMid= index2;
                break;
            }
            indexMid = (index1+index2) >>1;
            if(array[index1] == array[index2] && array[indexMid] == array[index1]) {
                //特殊情况:要用顺序查找
                return MinInOrder(array, index1, index2);
            }
            
            if(array[indexMid]>=array[index1]) {
                index1 = indexMid;
            }else if(array[indexMid]<=array[index2]) {
                index2 = indexMid;
            }
        }
        
        
        return array[indexMid];
    }
    /**
     * 在index1和index2之间顺序查找最小值
     * @param array 在此数组中进行查找
     * @param index1  开始索引位置
     * @param index2  结束索引位置
     * @return
     */
    private static int MinInOrder(int[] array,int index1,int index2) {
        int min = array[index1];
        for(int i=index1+1;i<=index2;i++) {
            if(min > array[i]) {
                min = array[i];
            }
        }
        return min;
    }
}

代码链接

剑指Offer代码-Java

posted @ 2019-08-05 12:21  这个世界~  阅读(91)  评论(0编辑  收藏  举报