旋转数组的最小值

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

解析:

        这是最近在看剑指offer,然后就看到这道题了,然后上面的解法有两种:1、也是最容易想到的一种,将数组按升序排序一下,然后数组的第一个数就是最小值,但是它的时间复杂度最好也必须为O(logN),(快排、归并、堆排序)。2、基于这种二分查找的思想,可以在一个局部有序的数组也可以使用二分查找,但剑指offer写出来的代码最开始是没有考虑{1,1,0,1,1,1}这种情况的,即使后面它把这种情况的程序考虑了写出来了,但我个人感觉他写的代码还是有点不够简洁,如果你和我也有同样的想法,那接下来你看我的代码就有意义了,都有注释,这里就不多说,直接上代码

#include <iostream>
#include <assert.h>
using namespace std;

//旋转数组的最小值
//3,4,5,6,7,1,2--->情况1
//6,7,1,2,3,4,5--->情况1
//[]闭区间
int min_key(int *arr,int low,int heigh)
{
	int begin=arr[low];
	int end=arr[heigh];
	while(low <= heigh)
	{
		int mid=low+(heigh-low)/2;
		//1,1,1,1,0,0
		if(arr[low] <= arr[mid] && arr[low] >= arr[heigh])//可以确定最小的数一定在右边
		{
			low=mid;
			if(heigh-low == 1)
				return arr[heigh] <arr[low] ? arr[heigh]:arr[low];
		}//可以确定最小的数一定在左边,而且这是一个连续递增的序列
		else if(arr[low] < arr[mid] && arr[low] < arr[heigh])
			return arr[low];
		//可以确定最小的数一定在右边,而且这是一个连续递减的序列
		else if(arr[low] > arr[mid] && arr[mid] > arr[heigh])
			return arr[heigh];
		//可以确定最小的数一定在左边
		else if(arr[low] >= arr[mid] && arr[mid] <= arr[heigh])
		{
			heigh=mid;
			if(heigh-low == 1)
				return arr[heigh] <arr[low] ? arr[heigh]:arr[low];
		}
	}
	return -1;
}
int min_value(int *arr,int len)
{
	assert(arr !=NULL);
	return min_key(arr,0,len-1);
}

int main()
{
	//int arr[]={3,4,5,6,7,1,2};
	//int arr[]={1,2,3,4,5,6,7};
	//int arr[]={7,6,5,4,3,2};
	//int arr[]={6,7,1,2,3,4};
	//int arr[]={1,1,1,1,0,0};
	//int arr[]={0,1,1,1,0,0};
	int arr[]={1,1,0,1,1,1};
	int len=sizeof(arr)/sizeof(*arr);
	int min=min_value(arr,len);
	cout<<"min is :"<<min<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值