📜  门| GATE-CS-2016(套装2)|第 50 题(1)

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

门 | GATE-CS-2016(套装2)|第 50 题
题目描述

有一个 n*n 的矩阵,它的每一行和每一列都是升序排列的。现在给定一个整数 x,查找矩阵中是否存在数 x。

函数签名
def search_in_matrix(matrix: List[List[int]], target: int) -> bool:
    pass
输入输出格式

输入格式

  • matrix:一个 n* n 的矩阵,每一行和每一列都是升序排列的。
  • target:一个整数。

输出格式

  • 如果 x 存在于矩阵中,则返回 True。
  • 如果 x 不存在于矩阵中,则返回 False。
示例

示例一

输入:

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
target = 5

输出:

True

示例二

输入:

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
target = 10

输出:

False
代码实现

题目要求查找一个数是否存在于矩阵中,时间复杂度要求尽可能小。由于矩阵的每行和每列都是升序排列的,因此我们可以考虑利用这个性质,每次比较矩阵的某个元素与目标值的大小关系:

  1. 如果该元素小于目标值,则该元素所在行的其他元素一定也小于目标值,因此我们需要搜索该元素所在行的右边部分;
  2. 如果该元素大于目标值,则该元素所在列的其他元素一定也大于目标值,因此我们需要搜索该元素所在列的上边部分;
  3. 如果该元素等于目标值,则找到目标值。

Python 代码

from typing import List

def search_in_matrix(matrix: List[List[int]], target: int) -> bool:
    # 矩阵为空,返回 False
    if not matrix:
        return False
        
    # 矩阵的行数和列数
    m, n = len(matrix), len(matrix[0])
    
    # 设置起始点为矩阵的右上角
    i, j = 0, n - 1
    
    # 搜索起始点右边和上边的所有元素,直到找到目标值或者搜索完整个矩阵
    while i < m and j >= 0:
        if matrix[i][j] == target:  # 找到目标值
            return True
        elif matrix[i][j] < target:  # 目标值在起始点下面的部分,搜索起始点下面一行
            i += 1
        else:  # 目标值在起始点左边的部分,搜索起始点左边一列
            j -= 1
    
    return False

时间复杂度

由于每次搜索都能将矩阵的规模缩小为原来的 1/2,因此时间复杂度为 $O(\log n)$。