Suppose we have a binary 2D matrix, now we have to find the beginning point and terminating point of all rectangles filled with 0s. We have to keep in mind that rectangles are separated and do not touch each other however they can touch the array boundary. A rectangle with only single element is also possible.
So, if the input is like −
1 | 0 | 1 | 1 | 1 | 0 | 1 |
1 | 1 | 0 | 1 | 1 | 1 | 1 |
1 | 0 | 1 | 1 | 0 | 0 | 1 |
1 | 0 | 1 | 1 | 0 | 0 | 1 |
1 | 0 | 1 | 1 | 0 | 1 | 1 |
1 | 0 | 1 | 0 | 0 | 0 | 0 |
1 | 1 | 1 | 0 | 0 | 0 | 1 |
1 | 0 | 1 | 1 | 1 | 0 | 1 |
then the output will be [[0, 1, 0, 1], [0, 5, 0, 5], [1, 2, 1, 2], [2, 3, 2, 4], [3, 1, 5, 1], [3, 4, 6, 5], [5, 3, 6, 5], [7, 1, 7, 1], [7, 5, 7, 5]]
To solve this, we will follow these steps −
- Define a function find_rect() . This will take i,j,a,output,index
- x := row count
- y := col count
- flag_col := 0
- flag_row := 0
- for m in range i to x, do
- if a[m, j] is same as 1, then
- flag_row := 1
- break
- if a[m, j] is same as 5, then
- do nothing
- for n in range j to y, do
- if a[m, n] is same as 1, then
- flag_col := 1
- break
- a[m, n] := 5
- if a[m, n] is same as 1, then
- if flag_row is same as 1, then
- insert m-1 at the end of output[index]
- otherwise,
- insert m at the end of output[index]
- if flag_col is same as 1, then
- insert n-1 at the end of output[index]
- otherwise,
- insert n at the end of output[index]
- if a[m, j] is same as 1, then
- From the main method, do the following −
- n := size of a
- op := a new list
- idx := -1
- for i in range 0 to n, do
- for j in range 0 to size of a[0], do
- if a[i, j] is same as 0, then
- insert [i,j] into op
- idx := idx + 1
- find_rect(i, j, a, op, idx)
- if a[i, j] is same as 0, then
- for j in range 0 to size of a[0], do
- display op
Example Code
Let us see the following implementation to get better understanding −
def find_rect(i,j,a,output,index): x = len(a) y = len(a[0]) flag_col = 0 flag_row = 0 for m in range(i,x): if a[m][j] == 1: flag_row = 1 break if a[m][j] == 5: pass for n in range(j, y): if a[m][n] == 1: flag_col = 1 break a[m][n] = 5 if flag_row == 1: output[index].append( m-1) else: output[index].append(m) if flag_col == 1: output[index].append(n-1) else: output[index].append(n) def get_coord(a): n = len(a) op = [] idx = -1 for i in range(0,n): for j in range(0, len(a[0])): if a[i][j] == 0: op.append([i, j]) idx = idx + 1 find_rect(i, j, a, op, idx) print (op) tests = [[1, 0, 1, 1, 1, 0, 1], [1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 0, 0, 1, 1], [1, 0, 1, 1, 0, 0, 1], [1, 0, 1, 1, 0, 1, 1], [1, 0, 1, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 1], [1, 0, 1, 1, 1, 0, 1]] get_coord(tests)
Input
[[1, 0, 1, 1, 1, 0, 1], [1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 0, 0, 1, 1], [1, 0, 1, 1, 0, 0, 1], [1, 0, 1, 1, 0, 1, 1], [1, 0, 1, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 1], [1, 0, 1, 1, 1, 0, 1]]
Output
[[0, 1, 0, 1], [0, 5, 0, 5], [1, 2, 1, 2], [2, 3, 2, 4], [3, 1, 5, 1], [3, 4, 6, 5], [5, 3, 6, 5], [7, 1, 7, 1], [7, 5, 7, 5]]