📜  门|门CS 2010 |第 45 题(1)

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

题目描述

在一个 n x m 的矩阵中,每行每列都是有序的。现在给定一个目标值 target,请你编写一个函数,判断矩阵中是否存在该目标值。

解题思路

由于每行和每列都是有序的,我们可以通过二分查找来快速定位每个元素在矩阵中的位置。具体步骤如下:

  1. 对矩阵的第一列进行二分查找,找到第一个大于等于目标值的元素所在行。若找不到,则目标值不在矩阵中;若找到了,记录该行的行号。

  2. 对矩阵第一行中从该行开始的所有元素进行二分查找,找到目标值所在的列。若找到了,说明目标值在矩阵中;否则,目标值不在矩阵中。

具体实现细节可参考下方的代码。

代码实现

def searchMatrix(matrix, target):
    """
    :type matrix: List[List[int]]
    :type target: int
    :rtype: bool
    """
    if not matrix or not matrix[0]:
        return False
    
    # 二分查找第一列,得到目标行的行号
    row = 0
    left, right = 0, len(matrix) - 1
    while left <= right:
        mid = (left + right) // 2
        if matrix[mid][0] == target:
            return True
        elif matrix[mid][0] < target:
            row = mid
            left = mid + 1
        else:
            right = mid - 1
    
    # 在目标行中二分查找目标值
    left, right = 0, len(matrix[0]) - 1
    while left <= right:
        mid = (left + right) // 2
        if matrix[row][mid] == target:
            return True
        elif matrix[row][mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    
    return False

复杂度分析

时间复杂度:$O(\log n + \log m)$,其中 $n$ 和 $m$ 分别是矩阵的行数和列数。二分查找第一列的时间复杂度为 $O(\log n)$,再进行一次二分查找的时间复杂度为 $O(\log m)$。

空间复杂度:$O(1)$。除了存储变量之外,我们并没有使用额外的数据结构。