zoukankan      html  css  js  c++  java
  • 剑指offer:旋转数组的最小数字

    题目

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

    解题思路

    这是一道二分查找的变形题,这里的旋转数组是两个有序的递增子数组拼接起来的,且前面一个子数组里的任意一个数都大于后面子数组中的数。而要找的最小值就是前后两个子数组的分界点。

    用三个指针begin、end、middle分别指向数组的首尾和中间元素

    1)若middle元素大于或者等于begin元素说明中间元素位于前半部分数组中,最小元素在后半部分的数组中,则将begin设为middle继续在后半部分中寻找

    2)若middle元素小于或者等于end元素说明中间元素位于后半部分数组中,最小部分在前半部分或者中间元素就是最小元素,则将end设为middle继续在前半部分中寻找

    这样不断缩小范围,直到最后begin和end会成为相邻的元素,此时end所指元素就是最小值

    特殊情况:

    1)0个元素旋转到后半部分,那么此时旋转数组就是一个非递减数组,最小值就是第一个元素,也就是为什么初始middle设为0的原因

    2)当begin、end、middle三个元素都相等时,无法判断中间元素在前半部分数组还是后半部分数组,只能遍历数组寻找最小值

    例如1,1,1,0,1和1,0,1,1,1都可以看成是0,1,1,1,1的翻转数组

    代码

     1     public int minNumberInRotateArray(int [] array) {
     2         if(array.length==0)
     3             return 0;
     4         int begin = 0,end = array.length-1,middle = 0;
     5         while(array[begin]>=array[end]){
     6             if((end-begin)==1){
     7                 middle = end;
     8                 break;
     9             }
    10             middle = (begin+end)/2;
    11             if(array[begin]==array[middle]&&array[middle]==array[end]){
    12                 return minInOrder(array,begin,end);
    13             }
    14             if(array[middle]>=array[begin]){
    15                 begin = middle;
    16             }else if(array[middle]<=array[end]){
    17                 end = middle;
    18             }
    19             
    20         }
    21         return array[middle];
    22     }
    23     
    24     private int minInOrder(int[] array,int begin,int end){
    25         int min = array[begin];
    26         for(int i = begin+1;i<end;i++){
    27             if(min>array[i]){
    28                 min = array[i];
    29             }
    30         }
    31         return min;
    32     }
  • 相关阅读:
    3D打印开源软件Cura分析(1) 【转】
    【机械臂】机械臂快速入门【转】
    Gcode命令【转】
    初识Vulkan【转】
    模型视图变换时,法线向量要乘模型视图矩阵的逆转置矩阵【转】
    OpenSceneGraphic 着色器中数组的应用【转】
    Docker容器的重启策略及docker run的--restart选项详解
    Linux LVM简明教程
    /etc/resolv.conf被自动修改
    ansible判断对指定主机组执行task , when: inventory_hostname in {{ groups['group'] }} does not work with dynamic inventory
  • 原文地址:https://www.cnblogs.com/huanglf714/p/11069485.html
Copyright © 2011-2022 走看看