请写出一个高效的在m*n矩阵中判断目标值是否存在的算法,矩阵具有如下特征:
每一行的数字都从左到右排序
每一行的第一个数字都比上一行最后一个数字大
例如:
对于下面的矩阵:
[
[1, 3, 5, 9],
[10, 11, 12, 30],
[230, 300, 350, 500]
] 要搜索的目标值为3,返回true; [
[1, 3, 5, 9],
[10, 11, 12, 30],
[230, 300, 350, 500]
] 要搜索的目标值为3,返回true; [[1,3,5,9],[10,11,12,30],[230, 300, 350, 500]],3
true
bool searchMatrix(vector<vector<int> > &matrix, int target){
int i=0, j=matrix[0].size()-1;
while(i<matrix.size() && j>=0){
if(matrix[i][j]==target){
return true;
}
else if(matrix[i][j]<target){
i++; //去掉这一行
}
else{
j--; //去掉这一列
}
}
return false;
}
/*
* 最优解法:Binary search on an ordered matrix
* 二分查找
* Runtime: 0 ms.Your runtime beats 75.27 % of java submissions
*/
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
return false;
int m = matrix.length, n = matrix[0].length;
int start = 0, end = m * n - 1;
// 二分查找
while (start <= end) {
int mid = start + (end - start) / 2;
int value = matrix[mid / n][mid % n];
if (target > value) {
start = mid + 1;
} else if (target < value)
end = mid - 1;
else
return true;
}
return false;
}
/*
* 解法二: Solution by me Runtime: 1 ms.Your runtime beats 6.66 % of java
* submissions. 刚开始指向右上角元素,如果target大于该元素,下移;如果target小于该元素,左移;
*/
public boolean searchMatrix_1(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
return false;
int m = 0, n = matrix[0].length - 1;
// 避免角标越界
while (m >= 0 && m < matrix.length && n >= 0 && n < matrix[0].length) {
if (target > matrix[m][n])
m++;
else if (target < matrix[m][n])
n--;
else
return true;
}
return false;
}
class Solution {
public:
bool searchMatrix(vector<vector<int> > &matrix, int target) {
int rows = matrix.size();
int cols = matrix[0].size();
int begin = 0,end = rows*cols-1;
while(begin <= end)
{
int mid = (begin + end)/2;
int row = mid/cols;
int col = mid%cols;
if(matrix[row][col] == target)
return true;
else if(matrix[row][col] < target)
begin = mid + 1;
else
end = mid - 1;
}
return false;
}
};
import java.util.*;
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0)
return false;
int m = matrix.length;
int n = matrix[0].length;
int head = 0;
int tail = m * n - 1;
while(head <= tail)
{
int mid = (head + tail)/2;
int value = matrix[mid/n][mid%n];
if(target == value)
return true;
if(target > value)
head = mid + 1;
else
tail = mid - 1;
}
return false;
}
}
class Solution {
public:
bool searchMatrix(vector > &matrix, int target) {
if (matrix.size() == 0 || matrix[0].size()==0) //if there is not element in matrix, return false;
return false;
/**
* search from the top-right, using binary-search
* if current element is larger than the target => row-=1
* if current element is smaller than the target => col+=1
*/
int row = 0;
int col = matrix[0].size()-1;
while (row = 0) {
int cur = matrix[row][col];
if (cur == target)
return true;
else if (cur > target)
col -= 1;
else
row += 1;
}
return false;
}
};
class Solution {
public:
//思路参考的下面分享的答案,把二维的表格看成是一维的数组
bool searchMatrix(vector<vector<int> > &matrix, int target) {
int row = matrix.size();
if(row == 0) return false;
int col = matrix[0].size();
int count = row * col;
int begin = 0;
int end = count-1;
while(begin <= end){
int mid = (begin + end)/2;
int a = mid/col;
int b = mid%col;
if(target == matrix[a][b]) return true;
else if(target >matrix[a][b]) begin = mid +1;
else end = mid -1;
}
return false;
}
};
class Solution {
public:
/**
*
* @param matrix int整型vector<vector<>>
* @param target int整型
* @return bool布尔型
*/
bool searchMatrix(vector<vector<int> >& matrix, int target) {
// write code here
int n = matrix.size() * matrix[0].size();
int left = 0;
int right = n - 1;
while (left <= right) {
int mid = (left + right) / 2;
int i = mid / matrix[0].size();
int j = mid % matrix[0].size();
int mid_val = matrix[i][j];
if (mid_val == target) return true;
if (mid_val > target) right = mid - 1;
if (mid_val < target) left = mid + 1;
}
return false;
}
}; 线性有序,转换下下标就行了
class Solution {
public:
/**
*
* @param matrix int整型vector<vector<>>
* @param target int整型
* @return bool布尔型
*/
bool searchMatrix(vector<vector<int> >& matrix, int target) {
const int m = matrix.size(), n = matrix[0].size();
int x = n - 1, y = 0;
while (x >= 0 && y < m) {
if (target == matrix[y][x]) return true;
if (target > matrix[y][x]) ++y;
else --x;
}
return false;
}
}; public class Solution {
/**
*
* @param matrix int整型二维数组
* @param target int整型
* @return bool布尔型
*/
public boolean searchMatrix (int[][] matrix, int target) {
// write code here
if(matrix == null || matrix.length == 0 || matrix[0].length == 0){return false;}
int m = matrix.length, n = matrix[0].length;
int l = 0, r = m * n - 1;
while(l < r){
int mid = l + (r - l) / 2;
int midNum = matrix[mid / n][mid % n];
if(midNum == target){return true;}
else if(midNum < target){l = mid + 1;}
else{r = mid;}
}
return matrix[l / n][l % n] == target;
}
} public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int i = 0, j = n - 1;
while (i < m && j >= 0) {
if (matrix[i][j] == target) {
return true;
} else if (matrix[i][j] > target) {
j--;
} else {
i++;
}
}
return false;
} import java.util.*;
public class Solution {
/**
*
* @param matrix int整型二维数组
* @param target int整型
* @return bool布尔型
*/
//二分查找
public boolean searchMatrix (int[][] matrix, int target) {
// write code here
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;
int m = matrix.length;
int n = matrix[0].length;
int start = 0,end = m*n-1;
while(start <= end){
int mid = (start+end)/2;
int val = matrix[mid/n][mid%n];
if(val < target){
start = mid+1;
}else if (val > target){
end = mid-1;
}else{
return true;
}
}
return false;
}
//普通方案,跑了一次,时间36ms,内存10864KB,接近二分
public boolean searchMatrix1 (int[][] matrix, int target) {
// write code here
//处理了两个边界值,第一个和最后一个元素
if(matrix == null || matrix.length == 0 || matrix[0].length == 0 || target < matrix[0][0]) return false;
int row = -1;
int m = matrix.length;
int n = matrix[0].length;
if(target > matrix[m-1][n-1]) return false;
//找到数据落在的行,可能是边界,如果恰好是边界,就返回
for(int i = 0; i<m; i++){
if(matrix[i][0] == target || matrix[i][n-1] == target) return true;
if(matrix[i][0] < target && matrix[i][n-1] > target) row = i;
}
//遍历对应行所有数据
for(int i = 0; i<n && row >= 0 ; i++){
if(matrix[row][i] == target){
return true;
}
}
return false;
}
}
class Solution {
public:
bool searchMatrix(vector<vector<int> > &matrix, int target) {
int r=matrix.size();
if(r==0)
return false;
int c=matrix[0].size();
for(int i=0;i<r*c;i++){
if(matrix[i/c][i%c]==target)
return true;
if(matrix[i/c][i%c]>target)
return false;
}
return false;
}
};
先纵向二分查找,再横向二分查找,复杂度为log(m) + log(n),
把二维当做一维的二分复杂度为log(n*m),
双向二分更优;
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length, n = matrix[0].length;
int up = 0, down = m - 1, mid = (up + down) / 2;
while(up <= down) {
if(matrix[mid][0] > target) {
// search up
down = mid - 1;
} else if(matrix[mid][n-1] >= target) {
// search in line
break;
} else {
//search down
up = mid + 1;
}
mid = (up + down) / 2;
}
if(up <= down) {
//search in line
int l = 0, r = n - 1;
int [] line = matrix[mid];
mid = (l + r) / 2;
while(l <= r) {
if(line[mid] > target) {
//search left
r = mid - 1;
} else if(line[mid] == target) {
return true;
} else {
//search right
l = mid + 1;
}
mid = (l + r) / 2;
}
return false;
} else {
return false;
}
}
}
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return false;
}
int rowLen = matrix.length;
int columnLen = matrix[0].length;
int start = 0, end = rowLen*columnLen-1;
while(start<=end) {
int mid = start+(end-start)/2;
int midVal = matrix[mid/columnLen][mid%columnLen];
if(midVal>target) {
end = mid-1;
} else if(midVal<target){
start=mid+1;
} else {
return true;
}
}
return false;
}
}
bool searchMatrix(vector<vector<int> > &matrix, int target) {
int rows=matrix.size();
int cols=matrix[0].size();
if(rows==0)
return false;
int i=0;
int j=cols-1;
while(i<=rows-1&&j>=0){
if(matrix[i][j]==target)
return true;
else if(matrix[i][j]<target)
i++;
else
j--;
}
return false;
public class Solution {
public static boolean searchMatrix(int[][] matrix, int target) {
int row = 0;
boolean isFinded = false;
for (int i = 0; i < matrix.length; i ++ ) {
if(target == matrix[i][matrix[0].length - 1]) return true;
else if(target < matrix[i][matrix[0].length - 1]) {
isFinded = true;
row = i;
break;
}
}
if( ! isFinded) return false;
for (int i = 0; i < matrix[0].length; i ++ ) {
if(matrix[row][i] > target) break;
else if(target == matrix[row][i]) return true;
}
return false;
}
}
class Solution {
public:
bool searchMatrix(vector<vector<int> > &matrix, int target) {
//Integers in each row are sorted from left to right.
//所以很容易想到二分查找
int row = matrix.size();
int col = matrix[0].size();
int l=0,h=row*col,m;
while(l<h){
m = l+((h-l)>>1);
int i=m/col;
int j=m%col;
if(matrix[i][j]>target){ //取左区间
h=m;
}else if(matrix[i][j]<target){ //取右区间
l=m+1;
}else{ //等于
return true;
}
}
return false;
}
};
/*
思路:排除
右上角数字是本行最大,本列最小。
当右上角大于目标数字,去前一列找。
当右上角小于目标数字,去下一行找。
*/
class Solution {
public:
/**
*
* @param matrix int整型vector<vector<>>
* @param target int整型
* @return bool布尔型
*/
bool searchMatrix(vector<vector<int> >& matrix, int target) {
if(matrix.size()==0){
return false;
}
int i=0;
int j=matrix[0].size()-1;
while(i<matrix.size() && j>=0){
//遇见,直接返回
if(target == matrix[i][j]){
return true;
}
//当前值小于目标
if(target > matrix[i][j]){
i++;
continue;
}
//当前值大于目标
if(target < matrix[i][j]){
j--;
continue;
}
}
return false;
}
}; if (matrix.length == 1) {
return Arrays.binarySearch(matrix[0], target) >= 0;
}
for (int i = 0; i < matrix.length; i++) {
if (target < matrix[i][0]) {
// 在上一行
if (i == 0) {
return false;
}
return Arrays.binarySearch(matrix[i - 1], target) >= 0;
} else if (target == matrix[i][0]) {
return true;
}
}
return false; bool searchMatrix(vector<vector<int> >& matrix, int target) {
int m = matrix.size(), n = matrix[0].size();
int left = 0, right = m * n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int i = mid / n, j = mid % n;
if (matrix[i][j] == target) return true;
if (matrix[i][j] > target) right = mid - 1;
else left = mid + 1;
}
return false;
}