在二维矩阵中找到最大数量为 0 的行

Posted

技术标签:

【中文标题】在二维矩阵中找到最大数量为 0 的行【英文标题】:Find the row(s) with maximum number of 0s in a 2-d matrix 【发布时间】:2011-12-14 06:47:00 【问题描述】:

问题

给定一个 2D 0/1 矩阵,找到最大数量为 0s 的行。

示例

11111000 11111110 11100000 11000000 11110000

输出

11000000


我的想法

如果每个0s 行是连续的,我们可以从两端扫描每一行。常识说用O(n^2)扫描。

O(n)的解决方案吗?

【问题讨论】:

C 还是 C++? 提示: 选择 C++! 只要称它为 mxm 矩阵并让 n = m^2 那么它就是 O(n) 没有O(n) 解决方案。有一些方法可以“优化”它,但“优化”只会在特定情况下有所帮助,实际上会使其他情况变得更糟。 @muntoo 与语言无关! 在您的示例中,所有行都以 1 开头并以 0 结尾,并且 0 后面永远不会跟着 1。这是二维矩阵的属性吗? 【参考方案1】:

如果每一行都像 1....10...0,您可以在每一行中对第一个零进行二进制搜索。

那就是 O(n*lg(n))

对于任意矩阵,你必须检查每个单元格,所以它必须是 O(n^2)。

【讨论】:

【参考方案2】:

您可以在O(N) 中进行如下操作:

A[i][j]i=0 and j=No_of_columns-1 开始。

           0, keep moving to the left by doing j--
A[i][j] = 
           1, move down to the next row by doing i++

当你到达最后一行或最后一列时,j的值就是答案。

伪代码:

Let R be number of rows
Let C be number of columns

Let i = 0
Let j = C-1   
Let max1Row = 0

while ( i<R && j>=0 )
   if ( matrix[i][j] == 0 )
      j--
      max1Row = i
   else
      i++
end-while


print "Max 0's = j"
print "Row number with max 0's = max1Row"

【讨论】:

+1,但是,正如我上面评论的,这是O(sqrt(n))。处理矩阵时,通常#rows*#cols == n 表示大 O 表示法[因为输入的大小是#rows*#cols,而n 代表输入的大小]。【参考方案3】:

正如@amit 所说:

扫描一个矩阵被认为是 O(n)。标准的大 O 表示法代表运行时间和输入大小之间的关系。由于您的输入大小为#rows*#cols,因此您应该将此数字视为n,而不是#rows。

因此,这是您可以得到的O(n)。 :)

std::vector<std::string> matrix;
std::vector<std::string>::iterator max = matrix.begin();

for(std::vector<std::string>::iterator i = matrix.begin(); i != matrix.end(); ++i)

    if(count_zeros(*i) > count_zeros(*max))
        max = i;

count_zeros() 应该如下所示:

size_t count_zeros(std::string s)

    size_t count = 0;

    for(std::string::iterator i = s.begin(); i != s.end(); ++i)
        if(*i == '0')
            ++count;

    return i;


如果all保证每一行的0s在最右边,你可以在O(sqrt(n))中做到。

    将光标放在(len, 0) 如果光标左侧的值为0,则将光标向左移动。否则,将其向下移动。 如果到达最后一行,终止。否则,请转到第 2 步。
std::vector<std::string> matrix;
std::vector<std::string>::iterator y = matrix.begin();

for(std::string::reverse_iterator x = (*y).rbegin(); x < matrix.rend(); )

    if(*x != '0')
    
        x -= (*y).rbegin();
        ++(*y);
        x += (*y).rbegin();
        continue;
    

    ++x;

【讨论】:

@Curi0us7 是的;不过,直到我阅读了阿米特的评论,我才意识到这一点。【参考方案4】:

对于给定的样本集(都是从 111 开始并以 000 结束,没有混合 1 和 0),可以简单地通过 A&(A xor B) 的测试在单遍中搜索该集以测试是否存在比前一行多或少为零——这是一个 O(n) 的循环......

【讨论】:

【参考方案5】:

这里只有一个 if 或每一行(不是每个元素)的快速解决方案: 由于您的矩阵只包含零和一,因此将每一行的元素相加,然后返回最小值/最小值的索引/索引。

P.S.:在 C++ 中使用 assmbly inc 或 ++Variable 时添加一个非常快

编辑:这里有另一个想法。如果您真的只需要不超过 64 列的 0/1 矩阵,您可以使用普通的无符号 64 整数将它们实现为位矩阵。通过设置和删除相应的位,您可以定义条目(0 或 1)。效果: o(n) 检查(如果我错了,请告诉我)如下m,其中 intXX 是 rowXX。第一个想法是通过异或提取不同的位

SET tmpA to int01
FOR I = 1 to n-1
  XOR intI with intI+1, store result in tmpX
  AND tmpX with intI, store result in tmpM
  AND tmpX with intI+1, store result in tmpN
  if (tmpN < tmpM)
    SET tmpA to intI+1
ENDFOR

tmpA 现在应该包含零最少的(最后)行。

干杯, G.

【讨论】:

以上是关于在二维矩阵中找到最大数量为 0 的行的主要内容,如果未能解决你的问题,请参考以下文章

openjudge1768 最大子矩阵[二维前缀和or递推|DP]

在python中找到二维矩阵(二维)中不同列表的最小值、最大值和平均值

MATLAB二维矩阵非零元素分布图

MATLAB二维矩阵非零元素分布图

2021-12-11:最大正方形。在一个由 ‘0‘ 和 ‘1‘ 组成的二维矩阵内,找到只包含 ‘1‘ 的最大正方形,并返回其面积。力扣221。

矩阵中求最大二维矩阵