二进制搜索矩阵

时间:2017-03-31 04:26:38

标签: algorithm matrix binary-search

  

编写一个有效的算法,搜索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

5 个答案:

答案 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! ");
    }
}

此函数打印要搜索的元素的行和列(如果存在)。如果希望函数根据搜索操作返回值,则可以修改此代码。