排序旋转数组查找(Search in a sorted, rotated list)

假设存在一个按升序排列的数组A,让A绕其中的一个元素旋转180度得到新的数组A1,如何在对数时间复杂度内完成对A1的查找呢?

对于A1这样的数组,我们仍可使用二分查找来找寻其中的元素,只是,在二分查找之前,需要找到其分界点,这样分界点的两边分别为增序数组,从而可以使用二分查找。因此上述问题的主要操作就是在找寻这个分界点。

例如a[6] = {4,5,6,1,2,3}这样的数组,我们需要找到元素6的索引,如何查找呢?首先我们可以设定一个最大值max为数组的最后一个元素,6左边的元素均大于max,6右边的元素均小于max,为此进行二分查找,如果a[mid]<max,则此时mid位于6的右边,因此将high=mid;如果a[mid]>max,则说明此时mid在6的左边,将low=mid,于此同时将max=a[mid],如果a[mid]=max说明此时max=6,返回mid

代码实现

int find_point(const int* a, const int n)
{
	int low = 0;
	int high = n-1;
	int max = a[n-1];
	while (low<high)
	{
		int mid = (low+high)/2;
		if(a[mid] < max)
			high = mid;
		else if(a[mid] > max)
		{
			max = a[mid];
			low = mid;
		}
		else
		{
			return mid;
		}
	}
	return -1;
}

上述查找分界点的时间为O(logn)。找到分界点之后即可利用二分查找来查询目标元素。

代码实现

int binary_search(const int* a, int low, int high, int target)
{
	while (low<=high)
	{
		int mid = (low + high)/2;
		if(a[mid] == target)
			return mid;
		else if(a[mid] > target)
			high = mid-1;
		else
			low = mid+1;
	}
	return -1;
}
int find_target(const int* a, const int n,const int target)
{
	int point = find_point(a,n);
	if(point == -1)
		return -1;
	if(target >= a[0])
		return binary_search(a,0,point,target);
	else
		return binary_search(a,point+1,n-1,target);
}

测试代码

using namespace std;
int find_point(const int* a, const int n);
int binary_search(const int* a, int low, int high, int target);
int find_target(const int* a, int n, int target);
void main()
{
	int a[] = {5,6,7,8,1,2,3,4};
	int n=8;
	for(int i=0; i<n; i++)
		cout<<a[i]<<" ";
	cout<<endl;
	int target;
	cout<<"Target: ";
	cin>>target;
	while(target>=0)
	{
		cout<<"Location: "<<find_target(a,n,target)<<endl;
		cout<<"Target: ";
		cin>>target;
	}
}
仅供参考考,欢迎拍砖

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值