04. 二维数组中的查找
一、题目描述
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
限制:
0 <= n <= 1000
0 <= m <= 1000
二、解题思路
1、线性查找法
思路:
由提示例可以观测到,二维数组的行从左至右依次增大,从上之下依次增大;
那么就可以利用这个规律进行查找;有两种思路:
1、从第一行最后一列matrix[0] [j]开始与目标值target比较
①、如果二维数组为空,则返回false;
②、如果当前值大于目标值target,则列-1;
③、如果当前值小于目标值target,则行+1;
④、当前值等于目标值target,则返回true;
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public: bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) { if(matrix.size() == 0) return false; int row = 0; int col = matrix[0].size() - 1; while(row < matrix.size() && col >= 0) { if(matrix[row][col] > target) col--; else if(matrix[row][col] < target) row++; else if(matrix[row][col] == target) return true; } return false; } };
|
2、从最后一行第一列matrix[i] [0]开始与目标值 (target) 比较
①、如果二维数组为空,则返回false;
②、如果当前值大于目标值target,则行-1;
③、如果当前值小于目标值target,则列+1;
④、当前值等于目标值target,则返回true;
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public: bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) { if(matrix.size() == 0) return false; int i = matrix.size() - 1; int j = 0; while(i >= 0 && j < matrix[0].size()) { if(matrix[i][j] > target) i--; else if(matrix[i][j] < target) j++; else return true; } return false; } };
|
复杂度分析:
时间复杂度:O(n+m)。访问到的下标的行最多增加 n 次,列最多减少 m 次,因此循环体最多执行 n + m 次。
空间复杂度:O(1)。
2、具体程序实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include <iostream> #include <vector> using namespace std;
class Solution { public: bool findNumberIn2DArray(vector<vector<int> > v, int target) { if(v.size() == 0) { return false; } int i = 0; int j = v[0].size() - 1; while(i < v.size() && j >= 0) { if(v[i][j] > target) { j--; } else if(v[i][j] < target) { i++; } else if(v[i][j] == target) { return true; } } return false; } };
int main() { vector<vector<int> > v1(5,vector<int>(5)); int arry[5][5] = { {1, 4, 7, 11, 15}, {2, 5, 8, 12, 19}, {3, 6, 9, 16, 22}, {10, 13, 14, 17, 24}, {18, 21, 23, 26, 30}}; for(int i = 0; i < 5; i++ ) { for(int j = 0; j < 5; j++) { v1[i][j] = arry[i][j]; } } Solution s; if(s.findNumberIn2DArray(v1,12)) { cout << "找到了" << endl; } else { cout << "没有找到" << endl; } return 0; }
|
输出:
程序具体的实现流程:
①、v[0] [5] = 15 < 12,因此列 j-1;
②、v[0] [4] = 11 < 12,因此行 i+1;
③、v[1] [4] = 12 = 12,输出找到了
参考链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/