【问题标题】:Time complexity analysis on Optimal Matrix Search(2D) problem最优矩阵搜索(2D)问题的时间复杂度分析
【发布时间】:2011-09-18 03:53:50
【问题描述】:

这将是我提出的一个相当大的问题,因为它需要对问题有深入而透彻的了解,以及迄今为止为获得最佳解决方案而采取的各种方法。

关于这个问题,我稍后会创建一个博客,因为我需要一点时间来写内容等等。所以,一旦准备好,我会提供我的博客链接。

不过,我发布此内容是为了让我们开始讨论。

第一件事:

问题如下:

编写一个在 n x m 表(二维>数组)中搜索值的高效算法。该表按行和列排序——即,

表[i][j] ≤ 表[i][j + 1] 表[i][j] ≤ 表[i + 1][j]。

需要注意的是,每一行和每一列都是单调排序的,即每一行和每一列都按非递减(字典顺序)排序。

对于实际问题和对此问题的精彩讨论,请点击以下链接:

注意:这篇文章有第 1,2 和 3 部分。

Searching 2D Matrix

来自澳大利亚格里菲斯大学的 Hong Shen 于 1995 年 12 月 27 日发表了该问题的最优解为 O(mlog(2n/m)) 的串行算法。

Hong Shen-- Generalized Optimal Matrix Search

从那时起,许多论坛讨论、博客以及在线和离线文章和出版物都对此进行了讨论,但截至今天,据我所知,O(((log(n))2) 是改进的二分搜索在本文中得到了最好的评价。

虽然没有提供详细的算法。

现在,我对这个问题做了不同的解决方案,希望使最优解低于当前最好的(我认为)

但是,我并不擅长分析算法的时间复杂度。

以下只是其中之一。当我们做出决定时,我会继续为其他人提供帮助,从而在您的帮助下做出最好的决定。

这里先给大家分析一下时间复杂度

  /*  NIAZ MOHAMMAD

    IntPol2d.cpp

    1. Find the interpolated mid along column
    2. Compare key with each elements in row-wise 
       along the found mid column
    3. IF failed
        DO 
        RECURSIVE call to IntPol2d 
        a. IF(key > a[row][mid])
            THEN SET l = mid + 1 and d = row - 1;
        b. ELSE set r = mid -1 and u = row;
*/


    bool intPol2d(int mat[][6], int M, int N, int target, int l, int u, int r, int d, int &targetRow, int &targetCol,int &count) {
      count++;
      if (l > r || u > d) return false;

      if (target < mat[u][l] || target > mat[d][r]) return false;

      int mid = l + ((target - mat[u][l])*(r-l))/(mat[d][r]-mat[u][l]);
      int row = u;

      while (row <= d && mat[row][mid] <= target) 
      {
        if (mat[row][mid] == target) 
        {
          targetRow = row;
          targetCol = mid;
          return true;
        }
        row++;
      }
      return intPol2d(mat, M, N, target, mid+1, u, r, row-1, targetRow, targetCol,count) ||
             intPol2d(mat, M, N, target, l, row, mid-1, d, targetRow, targetCol,count);

    }

如果您需要完整的可执行代码,请告诉我

感谢您的耐心和帮助,我们在讨论区见:

注意:@管理员或版主,如果这里不适合此类冗长问题,请告诉我,然后我将转到我的博客。

【问题讨论】:

  • “O(((log(n))2)”是什么意思,为什么不涉及m?你觉得你的代码复杂度是多少?如果不能分析复杂性,是什么让你如此有信心击败洪神?为什么你通过了 M 和 N 却从不使用它们?
  • 1.在提供的“搜索 2D 矩阵”的链接中声明了这一点,在这种情况下,他假设它是一个方阵。
  • 您是初学者?然后你正在尝试一个远远超出你技能的问题(并要求我们做这项工作)。从更简单的东西开始,比如一些基本的搜索和排序算法。一旦你掌握了这些,你就能更好地解决这样的问题。

标签: c++ c matrix code-analysis time-complexity


【解决方案1】:

您不必将数组视为二维事物。它只是一个 mat[n],其中 n=MxN 并进行复杂度 O(log(n)) 的二进制搜索。请注意,这是对数基数 2,是最坏的情况。请注意,复杂性不包括 1 以外的常量,因为它们不会随输入大小而变化。实际最坏的情况是测试了 2*log(n) 个元素。此外,您可能会在第一次测试中击中您想要的那个。如果不预先构建哈希表或其他关联数组,其中指向您要查找的原始矩阵中元素的指针位于新数组中的索引处,您将无法获得比这更快的速度。您需要值为 46 的元素,因此您在索引表中查看元素索引 46,也就是说,它指向 (M,N)=(2357,656)。在构建可重用、内存昂贵的索引表之后,繁荣,复杂度 O(1)。

【讨论】:

  • 不,我们不能只是展平数组,元素不是这样排序的。我们只知道对于每个元素,它的东部和南部邻居都比它大。所以像 [ 1 4 6 ][ 2 7 8] [ 5 8 9 ] 这样的矩阵是完全可能的,即 [ 1 4 6 2 7 8 5 8 9 ]。这是一个有趣而有趣的问题,真的。
  • 啊……我没听懂。每个矩阵有多少查找?换句话说,具有昂贵的一次性准备和廉价的重复查找的算法是否可行?
  • 所以二分搜索查找开始小于或等于的行的子集,然后在该子集中迭代以找到最后一个元素大于或等于的子集,然后在该子集的子集中进行二分搜索在行中查找列(如果您需要所有匹配项,则全部查找;如果您只需要一个匹配项,则查找第一个匹配项)。
  • 更糟糕的情况是:2*log(n)*n*2*log(3) -> O(n*log(n))
  • 还有更好的。 Here 对该问题的另一个stackoverflow 讨论,采用经典的O(n) 解决方案。如果你想自己发现,这里有一个提示:考虑东北和西南元素的特殊性质。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 2016-07-28
  • 1970-01-01
相关资源
最近更新 更多