您的位置:首页 > 其它

旋转数组的最小数字

2015-04-10 10:01 211 查看
题目:把一个递增数组的前几个元素移动到数组的末尾,我们称之为数组的旋转。输入一个递增排序数组的旋转,输出旋转数组的最小元素。例如输入3 4 5 6 7 1 2,则最小元素为1。规定递增元素是没有重复元素的。

分析:

1. 最简单做法是从头到尾遍历数组,就可以求出最小元素。时间复杂度O(n),但是这个是最朴素的方法。

2. 根据旋转数组的性质,旋转数组满足“递增-最小值-递增”的性质。利用这个性质我们可以比较快速的求出最小元素。例如3 4 5 6 7 - 1 - 2,就是满足递增-最小值-递增

    具体的做法是设置两个指针p1和p2,初始化分别指向数组的头和尾,然后比较两个指针所指的值和两个指针中间位置的值的关系。mid = (p1+p2) >> 1;

   (1)如果arr[mid] > arr[p2],说明最小元素在mid之后则p1 = mid

   (2)如果arr[mid]  < arr[p2],说明最小元素在mid之前则p2 = mid

   (3)如果两个指针相差为1的时候,最小值即为最小元素

    时间复杂度为O(logn),因为每次可以跳到中间位置,类似二分搜索。

 

3. 举例旋转数组3 4 5 6 7 1 2

    第一次p1指向3,p2指向2,mid指向6,发现arr[mid] > arr[p2]说明最小元素在mid之后,则p1 = mid

    第二次p1指向6,p2指向2,mid指向7,发现arr[mid] > arr[p2]说明最小元素在mid之后,则p1 = mid

    第三次p1指向7,p2指向2,mid指向1,发现arr[mid] < arr[p2]说明最小元素在mid之前,则p2 = mid

    第四次p1指向7,p2指向1,此时p1和p2差1,则最小元素为1.

4. 代码

[cpp] view
plaincopy





#include<iostream>  

#include<algorithm>  

using namespace std;  

  

//求最小元素  

int GetMinNum(int *arrNum, int n){  

    //不合法数据   

    if(arrNum == NULL || n <= 0){  

        return -1;  

    }  

    int left = 0;  

    int right = n-1;  

    while(left < right){  

        if(right == left+1){  

            return min(arrNum[left], arrNum[right]);  

        }  

        int mid = (left+right)>>1;  

        if(arrNum[mid] > arrNum[right]){  

            left = mid;  

        }  

        else{  

            right = mid;  

        }  

    }  

}   

  

int main(){   

    int arrNum[] = {3,4,5,6,7,1,2};  

    int value = GetMinNum(arrNum, 7);  

    cout<<value<<endl; //输出1   

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: