从多次循环移位后的数组中找出特定的元素

给定有n个元素的数组,将其循环移位多次,给定一个时间复杂度为O(log n) 的算法找出特定的元素。

Given a sorted array of n integers that has been rotated an unknown number of

times, give an O(log n) algorithm that finds an element in the array. 


A为所给的非递减数组。数组下标的最小和最大值为l u。x是要查找的元素。

数组A进行循环移位后一般情况下产生了两个非递减的序列。

具体如下图:



搜索元素由于是两个非递减子序列,所以可以采用二分搜索。

不过搜索时要注意先判断A[mid]在哪个子序列中。再针对不同的情况进行分析。注意:两个子序列相遇处未知。


SOLUTION

Assumptions:
A is the array. l and u are lower and upper indexes of the array. x is the key that we want to
search.
We can do this with a modification of binary search.
int search(int a[], int l, int u, int x) {
	while (l <= u) {
		int m = (l + u) / 2;
		if (x == a[m]) {
			return m;
		} else if (a[l] <= a[m]) {
			if (x > a[m]) {
				l=m+1;
			} else if (x >=a [l]) {
				u = m-1;
			} else {
				l = m+1;
			}
		}
		else if (x < a[m]) u = m-1;
		else if (x <= a[u]) l = m+1;
		else u = m-1;
	}
	return -1;
}


NOTE: What about duplicates? You may observe that the above function doesn’t
give you an efficient result in case of duplicate elements. However, if your array
has duplicate entries then we can’t do better than O(n) which is as good as linear
search.
For example, if the array is [2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2], there is no way to find element
3 until you do linear search.
在 IT Campus "NEIMARK",有几间绝密的房间,用于开发大型编程竞赛的问题。要进入这些房间,您必须选择正确的密码,打开一个圆形锁。密码每天都会更新。 今天的密码是 $1$ 到 $n$ 的数字的排列组合 $^{\text{∗}}$ ,其特性是在它的每一次循环移动 $^{\text{†}}$ 中,都有一个固定点。也就是说,在每一次循环移动中,都有一个元素等于它在排列中的位置。 输出任何满足这一条件的有效排列。请注意,有效的排列可能并不存在,那么请输出 $-1$ 。 $^{\text{∗}}$ 一个排列的定义是长度为 $n$ 的序列,由从 $1$ 到 $n$ 的整数组成,其中每个数字恰好出现一次。例如,(2 1 3)、(1)、(4 3 1 2)是排列;(1 2 2)、(3)、(1 3 2 5)不是排列。 $^{\text{†}}$ 数组循环移位是将最后一个元素移到数组的开头。长度为 $n$ 的排列恰好有 $n$ 个循环移位。**输入** 每个测试包含多个测试用例。第一行包含测试用例的数量 $t$ ( $1 \leq t \leq 500$ )。测试用例说明如下。 每个测试用例的单行包含一个整数 $n$ ( $1 \leq n \leq 2 \cdot 10^5$ )。 保证所有测试用例中 $n$ 的总和不超过 $2 \cdot 10^5$ 。**输入** 每个测试包含多个测试用例。第一行包含测试用例的数量 $t$ ( $1 \leq t \leq 500$ )。测试用例说明如下。 每个测试用例的单行包含一个整数 $n$ ( $1 \leq n \leq 2 \cdot 10^5$ )。 保证所有测试用例中 $n$ 的总和不超过 $2 \cdot 10^5$ 。**输出** 对于每个测试案例,输出所需的排列组合。如果存在多个解决方案,输出其中任意一个。如果没有合适的排列组合,则输出 $-1$ 。用C++编写以上代码,并讲解思路
03-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值