在1d和0s的2d数组中找到1s的矩形

时间:2013-04-12 07:17:24

标签: algorithm

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

3 个答案:

答案 0 :(得分:5)

<强>高级别

  • 跟踪最外面的1s。
  • 统计所有1。
  • 如果计数等于最外面的1s所包围的区域,我们有一个矩形。

<强>的伪代码:

left = width + 1
right = 0
top = height + 1
bottom = 0
count = 0

for x = 1 to width
for y = 1 to height
  if grid[x][y] == 1
    left   = min(left  , x)
    right  = max(right , x)
    top    = min(top   , y)
    bottom = max(bottom, y)
    count++

if count > 0 and count == (right-left+1)*(bottom-top+1)
  print "We have a rectangle!"
else
  print "We don't have a rectangle!"

答案 1 :(得分:0)

你可以这样解决:

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

此算法为O(n ^ 2),如果您只允许一个矩形,则该算法有效。如果你有多个矩形,那就太复杂了。

答案 2 :(得分:0)

我会做这样的事情(伪代码):

// 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 ?

在O(n)中运行。小心错误。

注意:大多数编程语言都有基于0的数组,因此您可能需要将i0循环到N - 1,对j也是如此。