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 }
  • 相关阅读:
    leetcode 122. Best Time to Buy and Sell Stock II
    leetcode 121. Best Time to Buy and Sell Stock
    python 集合(set)和字典(dictionary)的用法解析
    leetcode 53. Maximum Subarray
    leetcode 202. Happy Number
    leetcode 136.Single Number
    leetcode 703. Kth Largest Element in a Stream & c++ priority_queue & minHeap/maxHeap
    [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree
    正则表达式
    十种排序算法
  • 原文地址:https://www.cnblogs.com/General-up/p/5413162.html
Copyright © 2011-2022 走看看