【问题标题】:Given a matrix which only contains 0 and 1, and each row of the matrix is sorted, please find which row contains the most 1s给定一个只包含0和1的矩阵,矩阵的每一行都经过排序,请找出哪一行包含最多的1
【发布时间】:2017-12-09 19:37:10
【问题描述】:

给定一个只包含 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)。有没有人有其他解决方案?

【问题讨论】:

  • 从第一行一直到右边。然后向左移动直到到达最后一个1。将此存储为最大值,然后直接向下移动(相同的列位置)到下一行并重复。如果向下移动时不是1,请跳过该行。
  • 也不是 O(1) 空间!
  • @YvesDaoust 这个 O(1) 空间(正如你在下面的答案)
  • @javadba 他可能在谈论 op 的解决方案
  • @Sopel 啊好吧 - 我看到 @ljeabmreosn 评论说 O(1) - 以及正确的方法。

标签: algorithm matrix


【解决方案1】:

解决方法如下:

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

【讨论】:

  • 注意:我修复了这个答案,说“下一个 Q 向后而不是下一个 0 向后 - 这也使它对应于 python 代码。
  • 这个实现更好,因为它跳过了每行的最后 Q 个条目:如果最后 Q 中的任何一个是 0,那么该行的 1 将等于或少于已经看到的最佳行。跨度>
【解决方案2】:

请检查我的O(m + n) 实现。代码是用 C 编写的,但您可以轻松地将其转换为 Java。

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;
}

我从第一行和最后一列开始。当我得到第一个0 时,我会移动到下一行。我们应该最多只检查剩余的列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2018-08-01
    • 2018-09-07
    • 1970-01-01
    • 2021-12-21
    相关资源
    最近更新 更多