美文网首页
旋转数组的最小值

旋转数组的最小值

作者: senninha | 来源:发表于2017-04-26 19:33 被阅读13次

    旋转数组的最小值

    所谓旋转数组,即是递增有序数组旋转右移动若干位得到的数组,这里的右移和java里的>>>有点不同,像是汇编里的那个移动,流水灯的那个移动
    比如:

    1,2,3,4,5,6---->4,5,6,1,2,3

    因为这个可以是看成是已经有序的递增数组,所以可以用二分法,

    1. 选定一个中间数,若右边的数小于中间数,说明那个最小的数字应该处于中间的数字到右边的那个数字之间。包括边界的两个数字;

    2. 选定一个中间数,如果左边的数字大于中间的数字,说明最小的的那个数字应该在处于左边的数字到中间的数字之间。
    3. 情况3就比较奇葩了,如这个数组{5,1,2,3,5,5,5,5,5,5,5}
      第一次取的中间值是5,然后他和左边和右边的值都是一模一样的,导致根本就不知道是属于情况1还是2,所以这个时候就只能暴力遍历了。。当然暴力遍历也不能放弃之前筛选的成果,所以加上了左右边界。
    public static int findSmallestNumber(int[] array){
            //左边界的下标
            int left = 0;
            //右边界的下标
            int right = array.length - 1;
            
            for(int i = array.length ; i > 0 ; i = i / 2){
                int middle = array[(left + right) / 2];
                //情况1
                if(array[right] < middle){
                    left = (left + right) / 2;
                //情况2
                }else if(array[left] > middle){
                    right = (left + right) / 2;
                }else{
                    //这里就是情况3
                    return minInOrder(array, left, right);
                }
                   //最后当左右只差1的时候,最小的就是两者其一
                if(right - left == 1){
                    if(array[right] > array[left]){
                        return array[left];
                    }else{
                        return array[right];
                    }
                }
            }
            return -1;
        }
        
        private static int minInOrder(int[] array , int left , int right){
            int min = array[left];
            for(int i = left + 1; i <= right ; i++){
                if(array[i] < min){
                    min = array[i];
                }
            }
            return min;
        }
    
    

    相关文章

      网友评论

          本文标题:旋转数组的最小值

          本文链接:https://www.haomeiwen.com/subject/nndwzttx.html