写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数。
这个矩阵具有以下特性:
- 每行中的整数从左到右是排序的。
- 每一列的整数从上到下是排序的。
- 在每一行或每一列中没有重复的整数。
样例
考虑下列矩阵:
[
[1, 3, 5, 7],
[2, 4, 7, 8],
[3, 5, 9, 10]
]
给出target = 3,返回 2
挑战
要求O(m+n) 时间复杂度和O(1) 额外空间
解题思路1:
首先想到了是对每一行做二分查找。时间复杂度为O(nlogn),没能利用题目中每一列也是排好序的条件,不是最优解。
class Solution {
public:
/**
* @param matrix: A list of lists of integers
* @param target: An integer you want to search in matrix
* @return: An integer indicate the total occurrence of target in the given matrix
*/
int searchMatrix(vector<vector<int>> &matrix, int target)
{
// write your code here
int resNum = 0;
for(int i=0 ; i< matrix.size() ; i++)
if(binarySearch(matrix[i] , target) != -1)
resNum++;
return resNum;
}
int binarySearch(vector<int> & vec , int target)
{
int l = 0;
int r = vec.size()-1;
return binarySearch(vec , l , r , target);
}
int binarySearch(vector<int> & vec , int l , int r , int target)
{
if(l > r)
return -1;
int mid = (l+r) / 2;
if(vec[mid] == target)
return mid;
else if(vec[mid] < target)
return binarySearch(vec , mid+1 , r , target);
else
return binarySearch(vec , l , mid-1 , target);
}
};
解题思路2:
如果我们观察题目中给的那个例子,我们可以发现有两个位置的数字很有特点,左下角和右上角的数。例如右上角的7,往左所有的数变小,往下所有数增加,那么我们就可以和目标数相比较,如果目标数大,就往下搜,如果目标数小,就往左搜。这样就可以判断目标数是否存在。代码如下:
public class Solution {
/**
* @param matrix: A list of lists of integers
* @param target: An integer you want to search in matrix
* @return: An integer indicate the total occurrence of target in the given matrix
*/
public int searchMatrix(int[][] matrix, int target) {
// write your code here
int row = matrix.length;
int col = matrix[0].length;
int res = 0;
//从左下角开始搜索
int i = row-1, j = 0;
while(i >= 0 && j < col){
if(matrix[i][j] == target){
res++;
i--;
}else if(matrix[i][j] > target)
i--;
else
j++;
}
return res;
}
}

本文介绍了一种高效的算法,用于搜索一个m×n的矩阵中的特定值并返回其出现次数。矩阵的特点是每行每列都是排序的,且无重复元素。提出了两种解法,一种是逐行使用二分查找,时间复杂度为O(nlogn);另一种是从左下角开始,根据目标值调整搜索方向,达到O(m+n)的时间复杂度。
474

被折叠的 条评论
为什么被折叠?



