给定一个只包含0和1的矩阵,并对矩阵的每一行进行排序,请找到哪一行包含最多的1。对于M * N矩阵,需要O(M + N)时间复杂度,并且需要O(1)空间复杂度。
实施例
输入:
000000011111
000011111111
000000111111
000000000111
000000011111
000011111111
输出:
由于第2行和第6行都包含8个1,因此输出为[2,8],[6,8]。
我提出了一个解决方案:
public List<List<Integer>> mostOnes(int[][] a) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
for (int j = 0; j < a[0].length; j++) {
for (int i = 0; i < a.length; i++) {
if (a[i][j] == 1) {
List<Integer> res = new ArrayList<>();
res.add(i + 1);
res.add(a[0].length - j);
result.add(res);
}
}
if (result.size() != 0) break;
}
return result;
}
但是,它不是O(M + N)。有没有人有其他解决方案?
答案 0 :(得分:2)
解决方案如下:
Q= 0
For every row,
Search the next Q backward, starting from N - Q
Set the new Q there.
此过程停止,Q
表示1
的最大数量。
由于搜索是通过将索引从N
减少到0
(最差)来执行的,并且在M
行之间进行了分割,因此复杂度为O(N + M)
。诀窍是继续从一行继续搜索到当前列中的下一行,而不是从边缘重新开始。
Q= 0
for j in range(M):
for i in range(Q):
if A[j][N - 1 - i] == '0':
break
(不保证具体细节,但工作原理在那里。)
0000000|11111
0000|11111111
0000|00111111
0000|00000111
0000|00011111
0000|11111111
答案 1 :(得分:0)
请检查我的composer du
实施情况。代码是用C语言编写的,但很容易将其转换为Java。
O(m + n)
我从第一行和最后一列开始。当我第一次int FindRow(vector<vector<int>>& mat) {
int m = mat.size(), n = mat[0].size();
int i = 0, j = n - 1, mx = 0;
while (i < m && j >= 0) {
while (j >= 0 && mat[i][j] == 1) --j;
mx = max(mx, n - j - 1);
++i;
}
return mx;
}
时,我会转到下一行。我们最多只检查剩余的列。