剑指Offer算法实现之八:旋转数组的最小数字

来源:互联网 发布:网络暴力的危害 编辑:程序博客网 时间:2024/06/11 02:39

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.

思路:
① 题目并为说数组元素无重复
② “有序”数组的查找,考虑使用二分查找。找到“中位”元素,不满足条件,则“二分”缩小收缩范围
③二分查找的“变体”,注意特例

编译环境:ArchLinux+Clang3.3,C++

实现:

#include <iostream>#include <stdexcept>using namespace std;int findMin(int *a, int len){    if ( !a || len <= 0)        throw std::invalid_argument("Input error");    int idx1 = 0;    int idx2 = len -1;    int idxm = 0;    while (a[idx1] >= a[idx2]){ // 此处条件判断实际上仅用于首次循环前排除未旋转数组的情况        if (idx2 - idx1 == 1){            idxm = idx2;            break;        }        idxm = (idx1+idx2) / 2;        if (a[idx1] == a[idxm] && a[idxm] == a[idx2]){ // 遍历寻找最小值(三者相等时,不能用“二分”确定其中最小元素)            int min = a[idx1];            for (int i = idx1+1; i <= idx2; i++){                if (min > a[i])                    min = a[i];            }            return min;        }        if (a[idxm] >= a[idx1]) // idxm在左侧,缩小左半边            idx1 = idxm;        else  // idxm在右侧,缩小右半边            idx2 = idxm;    }    return a[idxm];}int main(){    int a[] = {1,0,1,1,1};    cout << findMin(a, sizeof(a)/sizeof(int)) << endl;    int b[] = {3,4,5,1,2};    cout <<  findMin(b, sizeof(b)/sizeof(int)) << endl;}

原创粉丝点击