搜索二维矩阵 II

GitHub跳转原题关系图返回列表

从右上角出发,小于 target 向下,大于 target 向左,每步排除一行或一列,O(m+n)。

OJ: leetcodecn

题目 ID: search-a-2d-matrix-ii

难度:普及+/提高

标签:数组二分查找分治矩阵cpppython

日期: 2026-07-28 22:05

题意

m×n 矩阵,每行从左到右递增,每列从上到下递增。查找 target 是否存在。

思路

暴力 O(mn)。利用矩阵的递增特性:从右上角开始,如果当前值小于 target 则向下(行递增),大于 target 则向左(列递减)。每步排除一行或一列,O(m+n)。

该思路与第 74 题(整体有序)不同:74 题的矩阵可扁平化为有序数组直接二分,而本题每行独立递增但跨行不保证连续。

代码

cpp
/**
 * Author by Rainboy
 */
// main.cpp:从右上角出发,小于 target 向下,大于 target 向左,O(m+n)。
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    bool searchMatrix(vector<vector<int>> &matrix, int target) {
        int m = matrix.size(), n = matrix[0].size();
        int i = 0, j = n - 1;
        while (i < m && j >= 0) {
            if (matrix[i][j] == target)
                return true;
            if (matrix[i][j] < target)
                i++;
            else
                j--;
        }
        return false;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int m, n, t;
    cin >> m >> n >> t;
    vector<vector<int>> a(m, vector<int>(n));
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            cin >> a[i][j];
    cout << Solution().searchMatrix(a, t) << '\n';
    return 0;
}
python
#!/usr/bin/env python3
from typing import List


class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        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
            if matrix[i][j] < target:
                i += 1
            else:
                j -= 1
        return False


def main() -> None:
    m, n, t = map(int, input().split())
    a = [list(map(int, input().split())) for _ in range(m)]
    print(Solution().searchMatrix(a, t))


if __name__ == "__main__":
    main()

复杂度

  • 时间复杂度:O(m+n),每步排除一行或一列。
  • 空间复杂度:O(1)。

总结

"右上角出发逐步缩小搜索范围"是杨氏矩阵搜索的标准方法,每次比较都能排除一整行或一整列。