在线性时间内找到最大的子矩阵

时间:2010-12-19 09:59:42

标签: algorithm

给定一个带n和n的n×n矩阵,找到最大的子 矩阵充满线性时间的那些。我被告知有一个解决方案 存在O(n)时间复杂度。如果n n n中有n ^ 2个元素 矩阵如何存在线性解?

4 个答案:

答案 0 :(得分:4)

除非你有一个非标准的子矩阵定义,否则这个问题从最大集团的减少就是NP难的。

答案 1 :(得分:1)

您无法在n x n时间内搜索n矩阵。反例:零个矩阵,单个元素设置为1。您必须检查每个元素以找到该元素的位置,因此时间必须至少为O(n^2)

现在,如果您说矩阵有N = n^2条目,并且您只考虑形成连续块的子矩阵,那么您应该能够通过沿着对角线走过来找到最大的子矩阵。矩阵,随时跟踪每个矩形。您通常可以同时激活O(sqrt(N))个矩形,并且您需要在其中搜索以确定哪个矩形是最大的,因此您应该能够在O(N^(3/2) * log(N))时间内执行此操作。

如果您可以选择任意行和列来形成子矩阵,那么我没有看到任何明显的多项式时间算法。

答案 2 :(得分:0)

解决方案的条目数是线性的,而不是行数或列数。

答案 3 :(得分:0)

public static int biggestSubMatrix(int[][] matrix) {

    int[][] newMatrix = new int[matrix.length][matrix[0].length];

    for (int i = 0; i < matrix.length; i++) {
        int sum = 0;
        for (int j = 0; j < matrix[0].length; j++) {
            if (matrix[i][j] == 1) {
                sum++;
                newMatrix[i][j] = sum;
            } else {
                sum = 0;
                newMatrix[i][j] = 0;
            }
        }
    }


    int maxDimention = 0;
    int maxSubMatrix = 0;

    for (int i = 0; i < newMatrix[0].length; i++) {
        //find dimention for each column
        maxDimention = calcHighestDimentionBySmallestItem(newMatrix, i);
       if(maxSubMatrix < maxDimention ){
          maxSubMatrix  = maxDimention ;
         }
     }
    return maxSubMatrix;


}

private static int calcHighestDimentionBySmallestItem(int[][] matrix, int col) {

    int totalMaxDimention =0;

    for (int j = 0; j < matrix.length; j++) {
        int maxDimention = matrix[j][col];
        int numItems = 0;
        int min = matrix[j][col];
        int dimention = 0;

        for (int i = j; i < matrix.length; i++) {
            int val = matrix[i][col];
            if (val != 0) {
                if (val < min) {
                    min = val;
                }
                numItems++;
                dimention = numItems*min;
                if(dimention>maxDimention){
                    maxDimention = dimention;
                }

            } else {  //case val == 0
                numItems = 0;
                min = 0;

            }
        }
        if(totalMaxDimention < maxDimention){
            totalMaxDimention = maxDimention;
        }

    }
    return totalMaxDimention;
}