zoukankan      html  css  js  c++  java
  • 旋转数组中的最小数字

      若是用直接查找的方法也就是一个一个比的方法(O(n)级别),虽然很容易解决,但显然根据旋转数组的规律,希望有更好时间效率的算法来解决。

      显然旋转数组可以用二分查找的方法来实现,考虑上面的例子,旋转数组中的第一个数一定是大于最后一个数的,然后要找的最小的数一定是两个递增序列的分界线(此数的左边递增,右边也递增),利用二分查找的思想,设置三个指针分别指向数组的开始(begin),结尾(end),和中间(mid),然后分析过程如下:

    但是注意要考虑到的几种特殊条件:

    1、若初始数组移动的是前0个元素,这也符合旋转数组的要求,即这种旋转数组本来就是排好序的数组,第一个数就是最小的元素。那么刚开始只需检测第一个数是否大于最后一个数,若小于,则直接返回第一个数就好。

    2、考虑如下的数:

    也就是说在这种情况下,当中间的数,最后一个数,第一个数都相等时,你是无法确定到底该往那边缩小查找范围,这种情况下只能利用O(n)级别的直接查找的方法。

    故综合上边的讨论可以写出的最终代码如下:

     1 #include<iostream>
     2 using namespace std;
     3 int findOrder(int elements[],int begin,int end)//特殊情况二的顺序查找
     4 {
     5     int key = elements[begin];
     6     for (int i = begin; i <= end; ++i)
     7     {
     8         if (elements[i] < key)
     9             return elements[i];
    10     }
    11 }
    12 int findInSpArray(int elements[], int length)
    13 {
    14     if (elements == nullptr || length <= 0)//若输入不符合,直接返回
    15         return 0;
    16     int begin = 0;
    17     int end = length - 1;
    18     int mid = begin;//便于出现特例一时直接返回第一个数
    19     while (elements[begin] >= elements[end])//每次缩小范围后不停的检测
    20     {
    21         if (end - begin == 1){//若范围减小到两个数,即end指向的一定是最小的数
    22             mid = end;
    23             break;
    24         }
    25         mid = (end + begin) / 2;
    26         if (elements[begin] == elements[end] && elements[begin] == elements[end])//若出现特例二
    27         {
    28             return findOrder(elements, begin, end);
    29         }
    30         if (elements[begin] < elements[mid])//最小数在begin之后
    31             begin = mid;
    32         else if (elements[end] > elements[mid])//最小数在end之前
    33             end = mid;
    34     }
    35     return elements[mid];//返回最小数
    36 }
    37 int main()
    38 {
    39     int a[5] = { 3, 4, 5, 1, 2 };
    40     cout << findInSpArray(a, 5) << endl;
    41     int b[5] = { 1, 2, 3, 4, 5 };
    42     cout << findInSpArray(b, 5) << endl;
    43     int c[5] = { 1, 0, 1, 1, 1 };
    44     cout << findInSpArray(c, 5) << endl;
    45     system("pause");
    46     return 0;
    47 }
  • 相关阅读:
    一键编译go文件命令.bat
    安装go语言,配置环境及IDE,只需3步
    Mysql show Status常用参数详解
    LFS:kernel panic VFS: Unable to mount root fs
    LFS: Interface eth0 doesn't exist
    转:Xshell显示找不到匹配的outgoing encryption算法怎么办
    NTP-ntpdate:no server suitable for synchronization found
    linux/module.h: No such file or directory 内核模块编译过程
    ASCII码表完整版
    [Firmware Warn]: GHES: Failed to read error status block address for hardware error source
  • 原文地址:https://www.cnblogs.com/General-up/p/5413162.html
Copyright © 2011-2022 走看看