📅  最后修改于: 2023-12-03 15:07:26.631000             🧑  作者: Mango
在二进制搜索(Binary search)中,我们通常要求输入数组是已排序的,然后通过递归或者循环将大问题分解成小问题,以此来降低时间复杂度,这也是二进制搜索比顺序搜索(Sequential search)更高效的原因之一。
那么当我们碰到一个未排序的数组时,能否仍然使用二进制搜索呢?
答案是 不一定。
虽然二进制搜索的前提条件是有序数组,但是如果我们对未排序的数组进行排序,然后再使用二进制搜索,这样做显然是可行的。但是前提是我们需要对数组进行排序,而排序本身需要花费 $O(nlogn)$ 的时间复杂度,因此我们需要权衡是否值得付出这样的代价。
如果我们不想对数组进行排序,我们仍然可以运用二进制搜索的思想,不过需要有所改进。
在未排序的数组中进行二进制搜索,我们可以将中心点与起始点和结束点进行比较,然后根据这个信息将问题分解成更小的问题。
具体的,假设当前正在搜索下标 $l$ 到 $r$ 的数组,我们首先求出中心点 $mid=(l+r)/2$。然后我们分三种情况考虑:
这种搜索方法的时间复杂度为 $O(logn)$,与二进制搜索的时间复杂度一致。但是由于问题特殊,每一次搜索的区间不再相等,因此这个算法并不能准确地称之为二进制搜索,更准确的命名是“旋转数组搜索”(Rotated Array Search)。
下面是一个用 Python 实现的旋转数组搜索的例子:
def rotated_array_search(arr, target):
l, r = 0, len(arr)-1
while l <= r:
mid = (l+r) // 2
if arr[mid] == target:
return mid
if arr[mid] >= arr[l]:
if arr[l] <= target < arr[mid]:
r = mid-1
else:
l = mid+1
else:
if arr[mid] < target <= arr[r]:
l = mid+1
else:
r = mid-1
return -1
以上是关于可以在未排序的数组中应用二进制搜索的讨论,希望能够帮助大家更好地理解这个算法。