如何减少这个问题的时间复杂度

时间:2019-04-27 10:51:21

标签: c++ algorithm time-complexity

最近在一次采访中有人问我这个问题,我想知道如何回答这个问题。

  

您具有任意顺序的二进制数字二维矩阵
  require 'openssl'; OpenSSL::SSL::SSLContext.new.ssl_version="TLSv1"
  0 0 0 0 0 0 0 0
  1 0 0 1 1 1 1 0
  1 0 0 0 1 1 1 1
  1 0 1 1 0 1 1 0
  1 1 0 0 0 0 1 1

     

您需要找到此模式的出现
  1 0 1 0 1 1 0 0
  1

因此,看一下上面的矩阵,很明显答案是 6 。 我这样解决了

11

下一个问题是获得更好的时间复杂度。 我无法回答确切的解决方案

有人可以帮我吗?我只是出于自己的好奇心想知道这一点。

3 个答案:

答案 0 :(得分:3)

这是一个小优化,取决于输入模式。

unsigned int Findpairs(const std::vector<std::vector<unsigned int>>& A) {
    unsigned int count = 0;

    for (unsigned int i = 0; i < (A.size() - 1); i++) {
        for (unsigned int j = 0; j < (A[i].size() - 1); j++) {
            if (A[i + 1][j + 1] == 1) {
                if (A[i + 1][j] == 1 && A[i][j] == 1) {
                    count++;
                }
            }
            else {
                j++; //skip a column because our bottom right saw 0
            }
        }
    }

    return (count);
}

答案 1 :(得分:0)

对于具体问题,您的解决方案是合适的。

如果您要在同一矩阵中查找其他模式,或者在矩阵非常大且模式较大的情况下,有两种替代方法将是有益的:

https://en.wikipedia.org/wiki/Summed-area_table

https://en.wikipedia.org/wiki/Discrete_Fourier_transform

两者都需要对原始矩阵进行一些预处理,但是随后将提供对模式模板的更快检查。您可以在OpenCV图像处理库中找到这两种实现。

答案 2 :(得分:0)

操作的时间复杂度可以描述为O(n),其中n是数组中的点数。您的操作等效于在未排序的数组中搜索某些内容。有几种方法可以提高算法的效率,但是您不能在少于线性时间O(n)的时间内执行这种类型的搜索。

对于某些问题,您可以通过首先排序或收集有关该问题的其他信息来提高时间复杂度。在此问题的情况下,您可以证明您的解决方案与数组的大小线性相关。对于随机数组,这3个元素中的每一个都有50%的几率发生。对于每一个n,模式出现的几率是0.5 ^ 3 = 1/8。这意味着您将数出大约1/8 * n个图案。 仅计算模式会花费O(n)时间。

如果您的目标是估计随机数组中的出现次数,则可以用O(1)时间来估算。该模式应该在随机数组中出现大约1/8 *(j-1)*(i-1)次。