Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Language agnostic 搜索排序矩阵的最有效方法?_Language Agnostic_Search_Matrix_Big O_Time Complexity - Fatal编程技术网

Language agnostic 搜索排序矩阵的最有效方法?

Language agnostic 搜索排序矩阵的最有效方法?,language-agnostic,search,matrix,big-o,time-complexity,Language Agnostic,Search,Matrix,Big O,Time Complexity,我有一个任务要写一个算法(不是用任何特定的语言,只是伪代码),它接收一个矩阵[size:mxn],该矩阵的排序方式是所有行都被排序,所有列都被单独排序,并在这个矩阵中找到某个值。我需要写出我能想到的最具时间效率的算法 矩阵看起来像: 1 3 5 4 6 8 7 9 10 我的想法是从第一行和最后一列开始,简单地检查值,如果值较大,则向下检查,如果值小于,则向左检查,并一直这样做,直到找到值或索引超出范围(如果值不存在)。该算法的线性复杂度为O(m+n)。有人告诉我,可以用对数复杂度来

我有一个任务要写一个算法(不是用任何特定的语言,只是伪代码),它接收一个矩阵[size:mxn],该矩阵的排序方式是所有行都被排序,所有列都被单独排序,并在这个矩阵中找到某个值。我需要写出我能想到的最具时间效率的算法

矩阵看起来像:

1  3  5
4  6  8
7  9 10

我的想法是从第一行和最后一列开始,简单地检查值,如果值较大,则向下检查,如果值小于,则向左检查,并一直这样做,直到找到值或索引超出范围(如果值不存在)。该算法的线性复杂度为O(m+n)。有人告诉我,可以用对数复杂度来实现。可能吗?如果是这样的话,怎么做?

这就是示例输入的外观?按对角线排序?当然,这是一种有趣的方式

由于下一行的值可能低于此行中的任何值,因此不能对给定的数据行进行任何特殊假设

我会(如果要求在一个大的输入上执行此操作)将矩阵读入一个列表结构,该结构将数据作为元组的一对,将mxn坐标作为元组的一部分,然后对矩阵快速排序一次,然后按值查找它

或者,如果每个位置的值都是唯一的,则将MxN数据放入在该值上键入的字典中,然后根据输入的键(或输入键的散列)跳转到MxN的字典条目

编辑:

请注意,如果您要多次查看矩阵,我上面给出的答案是有效的。如果只需要解析一次,那么这是最快的:

for (int i = 0; i<M; i++)
 for (int j=0; j<N; j++)
  if (mat[i][j] == value) return tuple(i,j);

for(int i=0;i在log M中,您可以获得一系列能够包含目标的行(对行的第一个值进行二进制搜索,对行的最后一个值进行二进制搜索,仅保留其第一个=目标的行)两次二进制搜索仍然是O(log M)
然后在O(logn)中,您可以再次使用二进制搜索来探索这些行中的每一行

这就是O(logM x logN)

tadaaaa

您的矩阵如下所示:

a ..... b ..... c
. .     . .     .
.   1   .   2   . 
.     . .     . .
d ..... e ..... f
. .     . .     .
.   3   .   4   .
.     . .     . .
g ..... h ..... i
input: X - value to be searched
until found
 divide matrix into 4 equal pieces
 get e,f,h,i as shown on picture
 if (e or f or h or i) equals X then 
   return found
 if X < e then quarter := 1
 if X < f then quarter := 2
 if X < h then quarter := 3
 if X < i then quarter := 4
 if no quarter assigned then 
    return not_found
 make smaller matrix from chosen quarter 
并具有以下特性:

a,c,g < i  
a,b,d < e
b,c,e < f
d,e,g < h
e,f,h < i
这看起来像一个O(logn),其中n是矩阵中的元素数。这是一种二维的二进制搜索。我无法正式证明它,但类似于典型的二进制搜索。

公共静态布尔查找(int a[][],int rows,int cols,int x){
public static boolean find(int a[][],int rows,int cols,int x){
    int m=0;
    int n=cols-1;
while(m<rows&&n>=0){
    if(a[m][n]==x)
        return1;
    else if(a[m][n]>x)
        n--;
    else m++;
}

}
int m=0; int n=cols-1; while(m=0){ 如果(a[m][n]==x) 返回1; else如果(a[m][n]>x) n--; else m++; } }
这是错误的答案

我真的不确定这些答案中是否有一个是最佳答案。我正在努力

  • 二进制搜索第一行和第一列,找出“x”可能所在的行和列。您将得到0、j和i,0。如果在此步骤中未找到x,则x将位于i行或j列
  • 在步骤1中找到的行i和列j上进行二进制搜索
  • 我认为时间复杂度是2*(logm+logn)


    如果输入数组是正方形(n*n),则可以减少常数,通过沿对角线进行二进制搜索。

    如何获取对角线,然后在对角线上进行二进制搜索,从右下角开始检查它是否在上面,如果是,则将对角线数组位置作为它所在的列,如果不是,则检查它是否在下面。每次点击对角线后,对该列运行二进制搜索(使用对角线的数组位置作为列索引)

    您可以获得上述算法的运行时间,并在需要时(在某个时刻)交换算法以对初始对角数组进行二进制搜索(这是考虑其n*n个元素,得到的x或y长度为O(1)作为x.length=y.length。即使在一百万*百万二进制搜索对角线时,如果它小于对角线的一半,则返回对角线,如果它不小于对角线,则返回到您所在的位置进行二进制搜索(当沿对角线进行二进制搜索时,这是对算法的轻微更改)1.我认为对角线搜索比按行进行的二进制搜索要好,我现在只是看数学题太累了:)

    顺便说一句,我认为运行时间与分析略有不同,您可以用最佳/最差/平均情况以及时间与内存大小的关系等来描述分析。因此,最好用“最差情况分析中的最佳运行时间是多少”来说明问题,因为在最佳情况下,您可以进行简单的线性扫描,并且项目可能位于fi中rst位置,这将是比二进制搜索更好的“运行时间”…

    这里是n的下界。从长度为n的未排序数组a开始。根据以下规则构造一个新矩阵M:次对角线包含数组a,它上面的所有内容都是负无穷大,下面的所有内容都是正无穷大。行和c对列进行排序,在M中查找条目与在A中查找条目是一样的。

    这是在的脉络中(我将从中窃取漂亮的图形)

    矩阵:

      min ..... b ..... c
        .       .       .
        .  II   .   I   . 
        .       .       .
        d .... mid .... f
        .       .       .
        .  III  .   IV  .
        .       .       .
        g ..... h ..... max
    
    Min和max分别是最小值和最大值。“mid”不一定是平均值/中值/任意值

    我们知道mid处的值>=象限II中的所有值,最大值 找不到退货 其他的 将中间值设置为最小值和最大值的平均值 如果目标==mid 中途返回 其他的 查找(b、f、目标),如果找到则返回 查找(d、h、目标),如果找到则返回 如果目标
    JavaScript解决方案:

    //start from the top right corner
    //if value = el, element is found
    //if value < el, move to the next row, element can't be in that row since row is sorted
    //if value > el, move to the previous column, element can't be in that column since column is sorted
    
    function find(matrix, el) {
    
      //some error checking
      if (!matrix[0] || !matrix[0].length){
        return false;
      }
      if (!el || isNaN(el)){
        return false;
      }
    
      var row = 0; //first row
      var col = matrix[0].length - 1; //last column
    
      while (row < matrix.length && col >= 0) {
        if (matrix[row][col] === el) { //element is found
          return true;
        } else if (matrix[row][col] < el) {
          row++; //move to the next row
        } else {
          col--; //move to the previous column
        }
      }
    
      return false;
    
    }
    
    //从右上角开始
    //如果value=el,则找到元素
    //如果值el,则移动到上一个
    
    //start from the top right corner
    //if value = el, element is found
    //if value < el, move to the next row, element can't be in that row since row is sorted
    //if value > el, move to the previous column, element can't be in that column since column is sorted
    
    function find(matrix, el) {
    
      //some error checking
      if (!matrix[0] || !matrix[0].length){
        return false;
      }
      if (!el || isNaN(el)){
        return false;
      }
    
      var row = 0; //first row
      var col = matrix[0].length - 1; //last column
    
      while (row < matrix.length && col >= 0) {
        if (matrix[row][col] === el) { //element is found
          return true;
        } else if (matrix[row][col] < el) {
          row++; //move to the next row
        } else {
          col--; //move to the previous column
        }
      }
    
      return false;
    
    }