编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入:
matrix =
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
输出: true
示例 2:
输入:
matrix =
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
输出: false
题目链接:中文题目;英文题目
说实话这道题有点难以相信是medium难度的…,放在easy里面应该也不算太难。不过我们也不要大意,争取一次accepted吧~ 这道题主要有两种思路吧:1)二分查找;2)双指针。
这里讲解一下主要的思路,代码用的是二分查找,至于双指针的思路和方法,大家可以参考这篇文章:33. Search in Rotated Sorted Array(搜索旋转排序数组)两种解法(C++ & 注释)
针对这道题,我们只需转换一下思路就可以了。如果是一维数组进行查找,直接用二分或双指针,现在我们以列数(matrix[0].size())对一维数组进行分割,然后查找,所以第一步,我们需要找到在哪一组进行二分查找。
因此,可以直接查找第一个比targe大的分组,即matrix[i][0] > target,那么我们需要第i - 1个组进行二分查找target;另外,需要注意一种特殊情况:
上面两个例子,我们发现如果查找的target属于最后一个分组,或者大于最后一个分组,那么按照上述方法的思路是找不到第一个比target大的分组,这种情况可以查找最后一个分组,看target是否包含在最后一个分组里面。
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (!matrix.size() || !matrix[0].size()) return false;
int rows = matrix.size(), columns = matrix[0].size(), rowsIdx = -1;
for (int i = 0; i < rows; i++) if (matrix[i][0] > target) { rowsIdx = i - 1; break; }
return rowsIdx == -1 ? binary_search(matrix[rows - 1].begin(), matrix[rows - 1].end(), target) : binary_search(matrix[rowsIdx].begin(), matrix[rowsIdx].end(), target);
}
};