【34】旋转数组的最小数字


题目:把一个递增数组的前几个元素移动到数组的末尾,我们称之为数组的旋转。输入一个递增排序数组的旋转,输出旋转数组的最小元素。例如输入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. 代码


#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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值