algorithm - 具有相同整数的最大子矩阵

标签 algorithm matrix language-agnostic dynamic-programming

有一个 MxN 大小的矩阵,其中包含整数。我们需要找到其中具有相同整数的最大尺寸子矩阵。例如:

1 2 2 4 5
1 2 2 8 7
3 2 2 6 1

这里最大的子矩阵大小为 3x2,其中全部为 2。我的想法是检查每个元素 arr[i][j] , arr[i][j+1] 、 arr[i+1]arr[j+1] 和 arr[i+1][j] 是否是相等与否。如果它们相等,那么我们可以以某种方式更新矩阵的最大大小。但我无法得出确切的解决方案。

我想知道我们是否可以利用动态编程。这是一个面试问题。

最佳答案

  1. 假设子矩阵的底行是固定的。那么每一列都可以表示为一对(值,高度),其中值是该行和列中元素的值,高度是该列中有多少个连续元素等于它。例如,如果矩阵是

    3 1 2 3 
    1 2 2 1
    3 2 2 1
    2 2 2 2
    

    我们看到的底行是 2(从零开始的索引),值分别是 (3, 1)、(2, 2)、(2, 3) 和 (1, 2)。

  2. 让我们将列分成几组,将具有相同值的相邻元素分组在一起(对于前面的示例,它是 {(3, 1)}、{(2, 2)、(2, 3)} 和{(1, 2)}。现在我们可以解决一个标准问题:给定一个值数组 h[i],找到 min(h[i], h[ i + 1], ..., h[j]) * (j - i + 1) 对于每个组内的所有 ij(有是一种使用堆栈的线性解决方案,如果需要的话我可以详细说明这一点)。它允许我们在线性时间内处理一行。

  3. 我们需要的最后一件事是有效地计算每行的(值,高度)数组。对于第一行来说这是微不足道的。因此,我们可以逐一迭代所有行和它们(当一个元素添加到列的底部时,(值,高度)对以两种可能的方式发生变化:它变成(new_value,1)或(值,高度+ 1))。

这些观察使我们能够在 O(M) 时间内处理一行。总时间复杂度为O(N * M)

这是一些代码(它不是完整的实现,它可能包含错误):

int solve() {
    int res = 0;
    Pair[] valueForColumn = new Pair[rowsCount];
    for (int col = 0; col < columnsCount; col++)
        valueForColunm[col] = new Pair(matrix[0][col], 1);
    res = Math.max(res, solveForRow(valueForColumn); 
    for (int row = 1; row < rowsCount; row++) {
        for (int col = 0; col < columnsCount; col++)
            if (matrix[row][col] == matrix[row - 1][col]) {
                valueForColumn[col].second++;
            } else {
                valueForColumn[col].first = matrix[row][col];
                valueForColumn[col].second = 1;
            }
        }
        res = Math.max(res, solveForRow(valueForColumn));
   }
   return res;
}

int solveForRow(Pair[] valueForColumn) {
    List<Integer> group = new ArrayList<>();
    int res = 0;
    for (int i = 0; i < valueForColumn.length; i++) {
        group.add(valueForColumn[i].second);
        if (i == valueForColumn.length - 1 
                || valueForColumn[i].first != valueForColumn[i + 1].first) {
            res = Math.max(res, solveForGroup(group));
            group.clear();
        }
    }
    return res;
}

int solveForGroup(List<Integer> heights) {
    // a stack-based algorithm 
    // with linear time complexity mentioned in 2. goes here
}

关于algorithm - 具有相同整数的最大子矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27779198/

相关文章:

c++ - 如何以素数为模计算非常大的二项式系数?

c - C 中简单配置参数的正确数据结构是什么?

c - MKL CBlas 错误

python - 是否可以在不使用for循环的情况下将矩阵A中的所有列与矩阵B中的每一列相乘?

javascript - 元胞自动机的相邻单元格计数

c# - 开发游戏 - 如何执行需要多个游戏循环的事情?

floating-point - 为什么 float 不正确?

python - Tensorflow 下一个词预测器错误

r - Bin Fu 的算法实现没有给出正确的结果

c - 冒泡排序,使所有以数字 5 结尾的数字按升序排列