📅  最后修改于: 2023-12-03 15:12:42.043000             🧑  作者: Mango
本题来自于 2014 年的 GATE-CS 考试第一套试卷的第 62 题。
题目要求实现一个函数,用于在一个排好序的数组中查找目标元素第一次出现的位置。如果数组中不存在目标元素,则返回 -1。
考虑到数组已经排好序,我们使用二分查找算法。具体来说,我们可以维护两个指针 left
和 right
,分别指向数组的首尾两个元素,然后计算它们的中间位置 mid
。如果 mid
位置的元素等于目标元素,那么说明目标元素第一次出现的位置一定不在 mid
的右半部分,将 right
指针移动到 mid
左端。如果 mid
位置的元素大于目标元素,那么说明目标元素第一次出现的位置一定不在 mid
的右半部分,将 right
指针移动到 mid
左端。如果 mid
位置的元素小于目标元素,则说明目标元素第一次出现的位置一定不在 mid
的左半部分,将 left
指针移动到 mid
右端。可以证明,在每次操作时,都能把查找区间的长度缩小一半。
def find_first_occurrence(arr, target):
"""
在排好序的数组 arr 中查找目标元素 target 第一次出现的位置。
如果数组中不存在目标元素,则返回 -1。
"""
left, right = 0, len(arr) - 1
result = -1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
result = mid # 更新结果
right = mid - 1 # 缩小查找区间到左半部分
elif arr[mid] > target:
right = mid - 1 # 缩小查找区间到左半部分
else:
left = mid + 1 # 缩小查找区间到右半部分
return result
因为每次查找都把查找区间的长度缩小一半,所以最坏情况下需要查找 $\log_2 n$ 次,其中 $n$ 是数组的长度。每次查找操作需要 $O(1)$ 的时间,因此总时间复杂度为 $O(\log n)$。