编写一个有效的算法,搜索m x n中的值 基质
此矩阵具有以下属性:
- 每行中的整数从左到右排序。
- 第一个整数 每行的大小等于或等于的最后一个整数 上一行。
示例:考虑以下矩阵:
[
[1,3,5,7],
[10,11,16,20],
[23,30,34,50]
] target = 3,返回1(1对应于true)返回0/1(如果元素不存在,则为0;如果元素为,则为1 目前)对于这个问题
我的解决方案适用于NetBeans但在网站上失败。任何帮助将不胜感激。 https://www.interviewbit.com/problems/matrix-search/
render
答案 0 :(得分:3)
好吧,你 做的第一件事就是,你不能将矩阵物理地连接成一维向量,因为这是O(N*M)
,它是线性的而不是我们想要的。
// Easy but TLE code
int Solution::searchMatrix(vector<vector<int> > &A, int B) {
vector<int> v;
for(auto a : A) v.insert(v.end(), a.begin(), a.end());
return binary_search(v.begin(), v.end(), B);
}
所以关键是,你必须直接在矩阵上进行二进制搜索,这几乎是一样的(除了你现在必须自己编写二进制搜索)。
由于您没有真正访问所有元素,因此O(lg (N*M))
// Less Easy but AC code
int Solution::searchMatrix(vector<vector<int> > &A, int B) {
int m = A.size(), n = A[0].size(), lo = 0, hi = m*n-1, mi, row, col;
while(lo <= hi){
mi = lo + ((hi-lo) >> 1);
row = mi / n;
col = mi % n;
if(A[row][col] == B) return 1;
else if(A[row][col] > B) hi = mi - 1;
else lo = mi + 1;
}
return 0;
}
答案 1 :(得分:1)
我认为共享程序似乎存在逻辑错误。
在第一个while循环中更新结束值时,如果结束值等于start,则无法更新biRow。
当我更新下面的代码时,它运作良好。
public class Solution {
public int searchMatrix(ArrayList<ArrayList<Integer>> a, int b) {
int r = a.size();
int c = a.get(0).size();
int start = 0;
int end = r - 1;
// default value is last row for edge case
int biRow = r -1; // row to search column
//binary search 1st value of rows
int mid = 0;
while (start <= end) {
mid = (start + end) / 2;
if ( b >= a.get(mid).get(0) && b <= a.get(mid).get(c-1)) {
break;
}
if (b < a.get(mid).get(0)) {
end = mid-1;
} else {
start = mid+1;
}
}
biRow = mid;
//binary search column of biRow
start = 0;
end = c-1;
while (start <= end) {
mid = (start + end) / 2;
if (b == a.get(biRow).get(mid)) {
return 1;
}
if (b < a.get(biRow).get(mid)) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return 0;
}
}
答案 2 :(得分:0)
您的行搜索循环中存在逻辑错误。我做了一个修正,我还添加了边界条件。这个算法的时间复杂度是O(logN)。
public class Solution {
public int searchMatrix(ArrayList<ArrayList<Integer>> a, int b) {
int r = a.size();
int c = a.get(0).size();
// return 0 if b is less than 1st element or greater than last element
if (b < a.get(0).get(0) || b > a.get(r - 1).get(c - 1))
return 0;
int start = 0;
int end = r - 1;
// default value is last row for edge case
int biRow = r - 1; // row to search column
// binary search 1st value of rows
while (start <= end) {
int mid = (start + end) / 2;
if (b == a.get(mid).get(0)) {
return 1;
}
if (b >= a.get(mid).get(0) && b <= a.get(mid).get(c - 1)) {
{
biRow = mid;
break;
}
}
if (b < a.get(mid).get(0)) {
end = mid - 1;
} else {
start = mid + 1;
}
}
// binary search column of biRow
start = 0;
end = c - 1;
while (start <= end) {
int mid = (start + end) / 2;
if (b == a.get(biRow).get(mid)) {
return 1;
}
if (b < a.get(biRow).get(mid)) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return 0;
}
}
答案 3 :(得分:0)
由于对行和列进行了排序,因此按照您所说的进行二进制搜索将是正确的。这是Ruby中的二进制搜索(在矩阵上)实现
def binary_search_on_matrix(matrix,target)
row_size = matrix.size
column_size = matrix[0].size
left_index = 0
right_index = (row_size * column_size) - 1
while (left_index <= right_index)
mid_point = left_index + ((right_index - left_index) / 2)
row = mid_point / column_size
col = mid_point % column_size
value = matrix[row][col]
if (value == target)
return true
elsif (value > target)
right_index = mid_point - 1
else
left_index = mid_point + 1
end
end
return false
end
答案 4 :(得分:-1)
您可以先将2D数组转换为1D数组并执行二进制搜索操作。您可以参考下面给出的代码:
void search(int a[][10],int search,int m,int n)
{
int arr[100],i=0,j=0,k=-1;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
arr[++k] = a[i][j];
int first = 0 , last = k-1 , middle = (first+last)/2;
while (first <= last)
{
if(arr[middle] < search)
{
first = middle + 1;
}
else if(arr[middle] == search)
{
printf("\n Element found at position:( %d , %d")",(middle/n)+1,(middle%n)+1);
printf(" \n Row : %d",(middle/n)+1);
printf("\n column : %d",(middle%n)+1);
break;
}
else
{
last = middle - 1;
}
middle = (first + last)/2;
}
if(first > last)
{
printf("\n Element not found! ");
}
}
此函数打印要搜索的元素的行和列(如果存在)。如果希望函数根据搜索操作返回值,则可以修改此代码。