如何识别位图中的方块?

时间:2013-12-19 23:39:20

标签: algorithm

我遇到了这个采访问题:

  • 在N x N二维布尔元素数组中,您如何确定这些值是否形成正方形?

例如:

true true true true
true false false true 
true false false true 
true true true true

形成一个正方形。

我想我必须首先检查中间是否有正方形(如果N是奇数,总是为真),然后以递归方式检查周边的值。

  • 这是最好的方法吗?还是有更好,更快的方式来查找?

1 个答案:

答案 0 :(得分:2)

平方可以由两点确定。让我们说左上角点(x1,y1)和右下角点(x2,y2)。我们将1用作true,将0用作false

考虑一个数组:

array = [None] * 5
array[0] = [1, 1, 1, 1, 0]
array[1] = [1, 0, 0, 1, 0]
array[2] = [1, 0, 0, 1, 0]
array[3] = [1, 1, 1, 1, 0]
array[4] = [1, 0, 0, 1, 0]

显然(0,0)(3,3)在这种情况下形成一个正方形。我们可以找到一个属性:

当且仅当:

时,才会形成一个正方形
  • 通过将两个行边框添加到一起,您将获得一系列2;  序列的长度等于两行边界之间的距离。

  • 通过将两个列边框添加到一起,您将获得一系列2; 序列的长度等于两个列边界之间的距离。


利用上面的属性,你会得到一个O(n^3)算法:

row_segment = []
col_segment = []
for v1 in range(len(array)):
    for v2 in range(v1+1, len(array)):
        add_row = [array[v1][col]+array[v2][col] for col in range(len(array))]
        add_col = [array[row][v1]+array[row][v2] for row in range(len(array))]
        row_distance = v2-v1
        row_sum = sum(add_row[:row_distance+1])
        col_sum = sum(add_col[:row_distance+1])
        for i in range(len(array)-row_distance):
            j = i+row_distance
            if row_sum == 2*(row_distance+1):
                row_segment.append([v1, i, v2, j])
            if col_sum == 2*(row_distance+1):
                col_segment.append([i, v1, j, v2])
            row_sum = row_sum - add_row[i] + add_row[j+1] if j+1 < len(array) else None
            col_sum = col_sum - add_col[i] + add_col[j+1] if j+1 < len(array) else None

for i in row_segment:
    if i in col_segment:
        print "Square ({x1}, {y1}) ({x2}, {y2})".format(x1=i[0], y1=i[1], x2=i[2], y2=i[3])

让我们进行一些测试:

测试1:

0 0 0 0 0
0 0 1 1 1
0 0 1 0 1
0 0 1 1 1
0 0 0 0 0

Square (1, 2) (3, 4)  

测试2:

0 0 0 0 0
1 1 1 1 1
1 0 1 0 1
1 1 1 0 1
0 0 1 1 1

Square (1, 0) (3, 2)   

测试3:

0 0 0 0 0
1 1 1 1 1
1 0 1 0 1
1 1 1 1 1
0 0 0 0 0

Square (1, 0) (3, 2)
Square (1, 2) (3, 4)  

测试4:

1 1 1 1 1
1 0 1 0 1
1 1 0 0 1
1 0 0 1 0
1 1 1 1 1   

No squares found