📜  门| GATE-CS-2014-(Set-1) |第 62 题(1)

📅  最后修改于: 2023-12-03 15:12:42.043000             🧑  作者: Mango

题目介绍

本题来自于 2014 年的 GATE-CS 考试第一套试卷的第 62 题。

题目要求实现一个函数,用于在一个排好序的数组中查找目标元素第一次出现的位置。如果数组中不存在目标元素,则返回 -1。

实现思路

考虑到数组已经排好序,我们使用二分查找算法。具体来说,我们可以维护两个指针 leftright,分别指向数组的首尾两个元素,然后计算它们的中间位置 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)$。