📣🥳🥳🥳📣
✨Hello! 如果这篇【文章】对你有帮助😄,希望可以给博主点个赞👍鼓励一下😘
📣🥳🥳🥳📣
🔎 题目描述
在一个 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
注意:本题与主站 240 题相同
📝 解题方法
【vector
类型的题目】
📌 两层循环法(暴力法)
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
//1.开两层循环
for (decltype(matrix.size()) i = 0; i < matrix.size(); ++i) {
if (matrix[i].size() == 0) break; //[[]]这种需做一个判断
for (decltype(matrix.size()) j = 0; j < matrix[i].size(); ++j) {
if (matrix[i][j] == target) {
return true;
}
}
}
//2.若从两层循环出来,说明不存在此元素,返回false
return false;
}
};
时间复杂度O(N*M);
空间复杂度O(1)。
但这道题顺序都排好了,明显就不是给一个一个暴力找的。如果用这个方法,估计面试官:“今天就到这儿吧,回去等通知😏”。
📌 逐行二分法
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
//1.逐行处理
for (decltype(matrix.size()) i = 0; i < matrix.size(); ++i) {
//2.对每行,即对每个matrix[i]执行二分查找,找到了返回true
if (!matrix[i].size()) break; //[[]]这种情况需做一个判断
auto front = matrix[i].begin(), rear = matrix[i].end()-1;
while (front <= rear) {
auto mid = front + (rear - front) / 2;
if (*mid == target) {
return true;
} else if (*mid > target) {
rear = mid - 1;
} else {
front = mid + 1;
}
}
}
//3.所有行都处理完仍没发现,返回false
return false; //
}
};
时间复杂度O(Nlog2M),容量越大优势越明显;
空间复杂度O(1)。
📌 二叉搜索树法
从右上角开始查找,比目标值小,往左找,比目标值大,往右找。这样最多只需要找N+M次就可以得到结果,时间复杂度为O(N+M)。
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if (matrix.size() == 0 || matrix[0].size() == 0) return false; //[]和[[]]这两种情况需做一个考虑
//1.从右上角开始
for (decltype(matrix.size()) i = 0, j = matrix[0].size()-1; i < matrix.size() && j >= 0;) {
if (matrix[i][j] == target) return true;
else if (matrix[i][j] > target) --j;
else ++i;
}
//2.如果还是从循环出来了,那说明没找的,返回false
return false;
}
};
一开始这样写会报错:runtime error: addition of unsigned offset
。
想起来decltype(matrix.size())
的类型是size_type
,无符号类型,j
不能减到-1。
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if (matrix.size() == 0 || matrix[0].size() == 0) return false; //[]和[[]]这两种情况需额外考虑
//1.从右上角开始
for (decltype(matrix.size()) i = 0, j = matrix[0].size()-1; i <= matrix.size() - 1 && j >= 0;) {
if (matrix[i][j] == target) return true;
else if (matrix[i][j] > target) { //比目标值大,往左走
if (j == 0) return false; //但得先判断再往左走会不会出界,如果出界了即j等于0直接返回false
--j; //往左走
}
else { //比目标值小,往下走
if (i == matrix.size() - 1) return false; //但得先判断再往下走会不会出界,如果出界了即i等于matrix.size()-1直接返回false
++i; //往下走
};
}
//2.实际上下面这个return不会被执行到,但for循环体外需要有一个return
return false;
}
};
或者👇
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if (matrix.empty() || matrix[0].empty()) return false;
for (auto j = static_cast<int>(matrix[0].size()) - 1, i = j - j; i <= static_cast<int>(matrix.size()) - 1 && j >= 0;) {
if (matrix[i][j] == target) return true;
else if (matrix[i][j] > target) j--;
else i++;
}
return false;
}
};
时间复杂度O(N+M),容量越大优势越明显;
空间复杂度O(1)。
✨如有问题欢迎在底下评论留言或私信!
如果这篇【文章】对你有帮助😄,希望可以给博主【点个赞👍】鼓励一下😘
❤️Thanks for your encouragement❤️