剑指offer OJ,旋转数组的最小数字

来源:互联网 发布:电脑数据库在哪里 编辑:程序博客网 时间:2024/05/20 02:27

时间限制:1秒空间限制:32768K
通过比例:15.05%
最佳记录:0 ms|8552K (来自 牛客841129号)
题目描述

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

思想:采用二分法,定义low,mid,high下标。如果[mid]<[low]代表mid处于旋转过的部分中,反之处于主体部分中,特殊情况[mid]=[low]分情况考虑,这里注意[mid]>[low]有可能是旋转位数为0的情况,需要加判定。

我的代码:

class Solution {public:    int minNumberInRotateArray(vector<int> rotateArray) {        int low, high, mid;        low = 0, high = rotateArray.size() - 1;        //数组为空;        if(high < 0) {            return 0;        }        //数组不为空;        //(1)数组只有一个或两个个元素;        if(low >= high - 1) {            if(rotateArray[low] < rotateArray[high]) {                return rotateArray[low];            }            else {                return rotateArray[high];            }        }        //(2)数组有三个或更多元素;        while(low < high - 1) {            //mid选择算法;            mid = (low + high)/2;            if(rotateArray[mid] > rotateArray[low]) {                //考虑旋转位数为0的情况;                if(rotateArray[mid] < rotateArray[high]) {                    return rotateArray[0];                }                else {                    low = mid;                }            }            else if(rotateArray[mid] < rotateArray[low]) {                high = mid;            }            else if(rotateArray[mid] == rotateArray[low]) {                if(rotateArray[mid] > rotateArray[high]) {                    low = mid;                }                else if(rotateArray[mid] < rotateArray[high]) {                    high = mid;                }                //特殊情况,不能判断mid归属;                else {                    int num = except(rotateArray);                    return num;                }            }        }        return rotateArray[low] > rotateArray[high] ? rotateArray[high] : rotateArray[low];    }    //至少有一半元素相同所以只能顺序遍历;private:    int except(vector<int> rotateArray) {        vector<int>::iterator it;        int min;        for(it = rotateArray.begin(); it != rotateArray.end(); it++) {            if(it == rotateArray.begin()) {                min = * it;            }            else {                min = min <= *it ? min : *it;            }        }        return min;    }};

如果数组较小直接遍历

class Solution {public:    int minNumberInRotateArray(vector<int> rotateArray) {        if(rotateArray.size() == 0) {            return 0;        }        else if(rotateArray.size() == 1) {            return rotateArray[0];        }        return except(rotateArray);};

在牛客网讨论区看到一个更简洁的代码,利用迭代器,省去了下标,看起来更加简洁,思想是当[mid]=[low]时将low自加一就行了,省去了繁琐的特殊情况考虑。

代码:

int minNumberInRotateArray(vector<int> rotateArray) {     size_t len = rotateArray.size();    if(len == 0)        return 0;    if(len == 1)        return rotateArray[0];    vector<int>::iterator low = rotateArray.begin();    vector<int>::iterator mid;    vector<int>::iterator high = rotateArray.end();    while(low <= high)    {        //防止迭代器失效        mid = low + (high - low)/2;        if(*mid >*high)        {            low = mid + 1;        }        else if(*mid < *high)        {            high = mid;        }        else        {            high = high-1;        }        if(low >= high)        {            break;        }    }        return *low;    } //防止迭代器失效这句我的理解是防止直接low + high造成地址空间溢出。
0 0
原创粉丝点击