在二维矩阵中找到最大数量为 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 矩阵,找到最大数量为
0
s 的行。
示例
11111000 11111110 11100000 11000000 11110000
输出
11000000
我的想法
如果每个0
s 行是连续的,我们可以从两端扫描每一行。常识说用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保证每一行的0
s在最右边,你可以在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中找到二维矩阵(二维)中不同列表的最小值、最大值和平均值
2021-12-11:最大正方形。在一个由 ‘0‘ 和 ‘1‘ 组成的二维矩阵内,找到只包含 ‘1‘ 的最大正方形,并返回其面积。力扣221。