写出一个高效的算法来搜索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;
}
}