Algorithm m×n矩阵中的最大平方数

Algorithm m×n矩阵中的最大平方数,algorithm,Algorithm,问题是: 给定一个包含1.s和0的M x N阶矩阵,你必须找到 可以形成的最大平方数。形成一个正方形 通过将包含1的相邻单元格分组。最大平方就是 不完全包含在另一个正方形中。极大平方 部分重叠部分应单独计算。单位平方 (侧面长度=1)也应计算在内。请注意,正方形是 已填充,即它们不能包含0.s。什么可能是最好的 算法 例如: 对于以下4x5矩阵,输入为: 输入和输出示例: 11001 11110 11011 11001 输出: 9 可能的4x4正方形在(0,0)和(1,0)处具有左上角 可能

问题是:

给定一个包含1.s和0的M x N阶矩阵,你必须找到 可以形成的最大平方数。形成一个正方形 通过将包含1的相邻单元格分组。最大平方就是 不完全包含在另一个正方形中。极大平方 部分重叠部分应单独计算。单位平方 (侧面长度=1)也应计算在内。请注意,正方形是 已填充,即它们不能包含0.s。什么可能是最好的 算法

例如:

对于以下4x5矩阵,输入为:

输入和输出示例:

11001
11110
11011
11001
输出:

9

可能的4x4正方形在(0,0)和(1,0)处具有左上角

可能的3x3正方形的左上角位于(0,0)、(1,0)、(2,0)、(0,1)、(1,1)、(2,1)

可能的2x2正方形的左上角位于(0,0)、(1,0)、(2,0)、(3,0)、(0,1)、(1,1)、(2,1)、(3,1)、(0,2)、(1,2)、(2,2)处

可能的1x1正方形在所有坐标上都有左上角

因此,算法可以如下所示:

从测试4x4开始,如果全部为1,则标记为属于4x4,并增加计数

然后测试3x3,如果所有1和未标记为属于4x4,则标记为属于3x3,并增加计数

然后测试2x2,如果所有1和未标记为属于4x4或3x3,则标记为属于2x2,并增加计数

然后测试1x1,如果为1且根本没有标记,则增加计数

返回计数

如何标记单元格将是特定于语言的。e、 对于C,我将使用一个位字段

编辑:为了好玩,我使用位集在Java中实现了这一点

import java.util.BitSet; 

public class Program
    {
    // Right-shift bits by 'n' places
    private static BitSet RightShift(BitSet x, int n)
        {
        return x.get(n, Math.max(n, x.length()));
        }

    // Test square of dimension 'size' with top-left at position (h,w) for maximal-ness
    public static boolean IsMaximalSquare(BitSet [][] matrix, int h, int w, int size)
    {
        boolean isMaximal = true;
        for (int a = 0; a < size; a++)
        {
            for (int b = 0; b < size; b++)
            {
                BitSet x = matrix[h + a][w + b];
                if (!x.get(0))
                    return false;
                x = RightShift(x, size + 1);
                if (!x.isEmpty())
                    isMaximal = false;
            }
        }

        if (!isMaximal)
            return false;

        for (int a = 0; a < size; a++)
        {
            for (int b = 0; b < size; b++)
                matrix[h + a][w + b].set(size);
        }

        return true;
    }

    // Populate a 2d array of bitsets from string array
    public static BitSet [][] BuildMatrix(String rows[])
    {
        BitSet [][] matrix = new BitSet[4][5];

        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                matrix[i][j] = new BitSet(5);
                matrix[i][j].set(0, '1' == rows[i].charAt(j));
            }
        }
        return matrix;
    }

    // Return number of maximal squares from string representation of array
    public static int Solve(String rows[])
    {
        BitSet [][] matrix = BuildMatrix(rows);

        int count = 0;

        for (int size = 4; size > 0; size--) // test squares of size 4x4, 3x3, 2x2 and 1x1
        {
            for (int h = 0; h < 5 - size; h++) // iterate the rows
            {
                for (int w = 0; w < 6 - size; w++) // iterate the columns
                {
                    if (IsMaximalSquare(matrix, h, w, size))
                        count++;
                }
            }
        }

        return count;
    }

    public static void main(String[] args)
        {
        String rows1[] = {"11001","11110","11011","11001"}; // original question
        String rows2[] = {"11111","11111","11111","11111"}; // additional test case 1
        String rows3[] = {"00000","00000","00000","00000"}; // additional test case 2
        String rows4[] = {"11100","11111","11111","00111"}; // additional test case 3
        String rows5[] = {"11101","11111","11111","10111"}; // additional test case 4

        System.out.println(Solve(rows1));
        System.out.println(Solve(rows2));
        System.out.println(Solve(rows3));
        System.out.println(Solve(rows4));
        System.out.println(Solve(rows5));
        }
    }
import java.util.BitSet;
公共课程
{
//按“n”位右移位
专用静态位集右移(位集x,int n)
{
返回x.get(n,Math.max(n,x.length());
}
//尺寸“尺寸”的测试平方,左上角位于位置(h,w)处,以获得最大尺寸
公共静态布尔IsMaximalSquare(位集[][]矩阵,int h,int w,int size)
{
布尔isMaximal=true;
对于(int a=0;a0;size--)//大小为4x4、3x3、2x2和1x1的测试方块
{
for(inth=0;h<5-size;h++)//迭代行
{
for(int w=0;w<6-size;w++)//迭代列
{
if(IsMaximalSquare(矩阵,h,w,大小))
计数++;
}
}
}
返回计数;
}
公共静态void main(字符串[]args)
{
字符串行1[]={“11001”、“11110”、“11011”、“11001”};//原始问题
字符串行2[]={“11111”、“11111”、“11111”、“11111”};//附加测试用例1
字符串行3[]={“00000”、“00000”、“00000”、“00000”};//附加测试用例2
字符串行4[]={“11100”、“11111”、“11111”、“00111”};//附加测试用例3
字符串行5[]={“11101”、“11111”、“11111”、“10111”};//附加测试用例4
System.out.println(Solve(rows1));
System.out.println(Solve(rows2));
System.out.println(Solve(rows3));
System.out.println(Solve(rows4));
系统输出打印LN(求解(第5行));
}
}
S(i,j)
为最大正方形的大小,右下角位于
(i,j)
。(我的索引从上到下,从左到右,从1开始。)整个
S
是一个
mxn
整数矩阵。计算
S
是动态规划中一个非常经典的问题,已知其时间复杂度为O(MN)。(如果你不记得了,这是怎么做的。假设
A
是输入矩阵。你设置
s(i,j)=0
if
A(i,j)=0
,设置
s(i,j)=min(s(i-1,j),s(i,j-1),s(i-1,j-1))+1
if
A(i,j)=1
。你可以设置
s(0,j)=s(i,j)=0
。)


然后通过检查矩阵
S
来提取最大平方。右下角位于
(i,j)
的正方形是最大的当且仅当
S(i,j)
非零且大于或等于
S(i+1,j)
S(i,j+1)
S(i+1,j+1)
。(如果您愿意,设置
S(M+1,j)=0
S(i,N+1)=0
)此步骤也需要O(MN)时间。

您尝试过什么?同时计算大小为1的正方形,这比9大得多(你有9个以上)有6个单位正方形和3个2x2正方形。@izomorphius我们需要找出最大正方形的数量,而不是普通正方形,最大正方形不能包含完整的正方形。它可以有交叉点,though@ShamimHafiz见acraig50