📌  相关文章
📜  查找未排序数组中元素的开始和结束索引(1)

📅  最后修改于: 2023-12-03 14:55:35.004000             🧑  作者: Mango

查找未排序数组中元素的开始和结束索引

在处理未排序数组时,我们可能需要查找某个值的开始和结束索引。这个问题可以使用两种方法解决:暴力法和二分法。

暴力法

暴力法的思路很简单:遍历整个数组,记录下目标值的开始和结束位置。实现起来也比较容易:

def searchRange(nums, target):
    start, end = -1, -1
    for i in range(len(nums)):
        if nums[i] == target:
            if start == -1:
                start = i
            end = i
    return [start, end]

上述代码首先将开始和结束索引初始化为-1,然后遍历整个数组,如果发现目标值,就更新开始和结束索引。如果开始索引还没有被找到,就把它更新为当前位置;如果已经找到了开始索引,就把结束索引更新为当前位置。最后返回结果即可。

这种方法的时间复杂度是O(N),其中N是数组的长度。如果数组很大,这种方法的效率可能会很低。

二分法

二分法的思路是:先用二分法查找目标值,找到之后再向左向右扩展,直到找到开始和结束位置。

def searchRange(nums, target):
    def binsearch(l, r, t):
        while l <= r:
            mid = (l + r) // 2
            if nums[mid] < t:
                l = mid + 1
            elif nums[mid] > t:
                r = mid - 1
            else:
                return mid
        return -1

    pos = binsearch(0, len(nums) - 1, target)
    if pos == -1:
        return [-1, -1]

    start, end = pos, pos
    while start > 0 and nums[start - 1] == target:
        start -= 1
    while end < len(nums) - 1 and nums[end + 1] == target:
        end += 1

    return [start, end]

上述代码使用了递归的二分法实现,先查找到目标值的位置pos,然后再向左和向右扩展,直到找到开始和结束位置。如果没有找到目标值,就直接返回[-1, -1]。

这种方法的时间复杂度是O(log N + K),其中N是数组的长度,K是目标值的个数。当目标值的个数较少时,这种方法的效率会更高。

总之,无论使用哪种方法,都要谨慎处理边界条件,保证程序的正确性。