74. 搜索二维矩阵
编写一个高效的算法来判断 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
解题
先找到target可能在的那一行,再找target在不在那一行;
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
m=matrix.size(); //行的最后一个
if(!m) return false;
n=matrix[0].size(); //列的最后一个
if(!n) return false;
if(target<matrix[0][0]||target>matrix[m-1][n-1]) return false;
//先找到在哪行
int row = findrow(matrix,target);
cout<<row;
//在row行查找
int left=0,right = n-1;
while(left<=right){
int mid= left+(right-left)/2;
if(matrix[row][mid]==target) return true;
else if(matrix[row][mid]>target) right=mid-1;
else left= mid+1;
}
return false;
}
private:
int m,n;
int findrow(vector<vector<int>>& matrix, int target)
{
int left=0;int right=m-1;
while(left<right)
{
int mid=left+(right-left)/2;
if(target<=matrix[mid][n-1]) right=mid;
else left=mid+1;
}
return left;
}
};
240. 搜索二维矩阵 II
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
示例:
现有矩阵 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。
解题
遍历每一行,若范围允许,则二分该行查看是否存在target;
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
m=matrix.size();
if(!m) return false;
n=matrix[0].size();
if(!n) return false;
if(target<matrix[0][0]||target>matrix[m-1][n-1]) return false;
//从坐左上到右下的每一条对角线为升序
//查找在哪一条对角线上
//每一行满足条件的照一次
int res=false;
for(int i=0;i<m;i++)
{
if(matrix[i][0]<=target&&matrix[i][n-1]>=target)
res=res||rowfind(matrix,target,i);
if (res) break;
}
return res;
}
private:
int m;
int n;
int colfind(vector<vector<int>>& matrix, int target,int col){
//在该列中找target
int left=0,right=m-1; //遍历该列的每一行
while(left<=right){
int mid=left+(right-left)/2;
if(matrix[mid][col]==target) return true;
else if(matrix[mid][col]<target) left=mid+1;
else right =mid-1;
}
return false;
}
int rowfind(vector<vector<int>>& matrix, int target,int row){
//在该行中找target
int left=0,right=n-1; //遍历该行的每一列
while(left<=right){
int mid=left+(right-left)/2;
if(matrix[row][mid]==target) return true;
else if(matrix[row][mid]<target) left=mid+1;
else right =mid-1;
}
return false;
}
};
也可遍历对角线,遍历每一行对角线左右可能存在target的位置;
解法2:从左下角开始,遇到比target大的上移,遇到比target小的右移,遇到target返回true,到边界外返回false;
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
m=matrix.size();
if(!m) return false;
n=matrix[0].size();
if(!n) return false;
if(target<matrix[0][0]||target>matrix[m-1][n-1]) return false;
//从坐左上到右下的每一条对角线为升序
//查找在哪一条对角线上
//每一行满足条件的照一次
int i=m-1;
int j=0;
while(i>=0&&j<n)
{
if(matrix[i][j]==target) return true;
else if(matrix[i][j]>target)
i--;
else j++;
}
return false;
}
private:
int m;
int n;
};
左下角为最后一行的最小值,第一列的最大值,若target大于该值,则只可能在右边;
若target小于该值,则只可能在上面;