从右上角出发,小于 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)。
总结
"右上角出发逐步缩小搜索范围"是杨氏矩阵搜索的标准方法,每次比较都能排除一整行或一整列。