Algorithm 在1和0的2d数组中查找1的矩形

Algorithm 在1和0的2d数组中查找1的矩形,algorithm,Algorithm,我有一个2d对象数组,如果该对象的clicked属性设置为true,则应将其视为“1”,否则为“0”。这些是选定的块。我需要检查所选框是否形成单个矩形。解决这个问题的最佳方法是什么?您可以这样解决: 搜索第一个元素,该元素为1 水平地向右走,然后向下走,然后向左走,然后向上走 如果你回到原点,你有一个矩形 然后确保所有其他元素均为0 该算法是O(n^2),如果只允许一个矩形,则该算法有效。如果有多个矩形,它会变得复杂。我会这样做(伪代码): //二维数组/矩阵(N是行数,M是列数) m[N]

我有一个2d对象数组,如果该对象的clicked属性设置为true,则应将其视为“1”,否则为“0”。这些是选定的块。我需要检查所选框是否形成单个矩形。解决这个问题的最佳方法是什么?

您可以这样解决:

  • 搜索第一个元素,该元素为1
  • 水平地向右走,然后向下走,然后向左走,然后向上走
  • 如果你回到原点,你有一个矩形
  • 然后确保所有其他元素均为0

该算法是O(n^2),如果只允许一个矩形,则该算法有效。如果有多个矩形,它会变得复杂。

我会这样做(伪代码):

//二维数组/矩阵(N是行数,M是列数)
m[N][m]=。。。
//包含1的左上角对象的x坐标
baseM=-1
baseFound=false
//矩形的预期宽度
宽度=0
宽度锁定=错误
//在我们开始识别一个矩形并遇到它之后,这被设置为true
//为扩展矩形,对象应为1的行
//是0。
HeightExceed=错误
//循环矩阵
对于i=1到N://行
//在一行的开头,如果我们已经找到了一个底部,请锁定宽度
//(不能大于基准行中的1个数)
如果baseFound:widthLocked=true
对于j=1到M://列
如果m[i][j]==1:
如果未找到,请执行以下操作:
baseM=j,baseFound=true
宽度=1
其他:
如果j=宽度:返回false
其他:
宽度=j-基米
elseif baseFound:
如果已锁定:
//检查我们是否留下了矩形并记住它
如果j==baseM:heightExceed=true
如果未超出高度:
//检查矩形中的对象是否为0
如果j>baseM&&j
在O(n)中运行。小心虫子


注意:大多数编程语言都有基于0的数组,因此您可能需要将
i
0
循环到
N-1
,这与
j
高级:

  • 跟踪最外层的1
  • 数一数所有的1
  • 如果计数等于最外面的1包围的面积,我们有一个矩形
伪代码:

left=宽度+1
右=0
顶部=高度+1
底部=0
计数=0
对于x=1到宽度
对于y=1到高度
如果网格[x][y]==1
左=最小值(左,x)
右=最大值(右,x)
顶部=最小值(顶部,y)
底部=最大值(底部,y)
计数++
如果计数>0且计数==(右-左+1)*(底部-顶部+1)
打印“我们有一个矩形!”
其他的
打印“我们没有矩形!”

如果矩形必须填充怎么办?@DeanHarber:然后使用Dukelings算法使用这个,它比我的解决方案简单得多。这个解决方案的美妙之处令人钦佩。如果我错了,请纠正我,但它应该是min(左,Y)和max(右,Y)而不是X吗?@Koba修复了,谢谢。(
top
bottom
y
相关,而不是
left
right
,至少根据实现情况)
// your 2d-array / matrix (N is the number of lines, M the number of columns)
m[N][M] = ...

// x coord of top left object containing 1
baseM = -1
baseFound = false
// expected width of rectangle
width = 0
widthLocked = false

// this is set to true after we started recognizing a rectangle and encounter
// a row where the object expected to be 1 in order to extend the rectangle
// is 0.
heightExceeded = false

// loop over matrix
for i = 1 to N: // lines
    // at the beginning of a line, if we already found a base, lock the width
    // (it cannot be larger than the number of 1s in the row of the base)
    if baseFound: widthLocked = true

    for j = 1 to M: // columns
        if m[i][j] == 1:
            if not baseFound:
                baseM = j, baseFound = true
                width = 1
            else:
                if j < baseM:
                    // not in rectangle in negative x direction
                    return false
                if heightExceeded:
                    // not in rectangle in y direction
                    return false
                if widthLocked:
                    // not in rectangle in positive x direction
                    if j - baseM >= width: return false
                 else:
                    width = j - baseM
        elseif baseFound:
            if widthLocked:
                // check if we left the rectangle and memorize it
                if j == baseM: heightExceeded = true
                if not heightExceeded:
                    // check if object in rectangle is 0
                    if j > baseM && j < baseM + width: return false
if baseFound:
    return true
else:
    // what is the expected result if no rectangle has been found?
    return ?