Most efficient algorithm to find the biggest square in a two dimension map
algorithm
Solution
Here is how to do this in the optimal amount of time, O(nm). This is built on top of @dukeling's insight that you never need to check a solution of size less than your current known best solution.
The key is to be able to build a data structure that can answer this query in O(1) time.
- Is there an obstacle in the square whose top left corner is at r, c and has size k?
To solve that problem, we'll support answering a slightly harder question, also in O(1).
- What is the count of items in the rectangle from r1, c1 to r2, c2?
It's easy to answer the square existence question with an answer from the rectangle count question.
To answer the rectangle count question, note that if you had pre-computed the answer for every rectangle that starts in the top left, then you could answer the general question for from r1, c1 to r2, c2 by a kind of clever/inclusion exclusion tactic using only rectangles that start in the top left
c1 c2
-----------------------
| | | |
| A | B | |
|_____________|____| | r1
| | | |
| C | D | |
|_____________|____| | r2
|_____________________|
We want the count of stuff inside D. In terms of our pre-computed counts from the top left.
Count(D) = Count(A ∪ B ∪ C ∪ D) - Count(A ∪ C) - Count(A ∪ B) + Count(A)
You can pre-compute all the top left rectangles in O(nm) by doing some clever row/column partial sums, but I'll leave that to you.
Then to answer the to the problem you want just involves checking possible solutions, starting with solutions that are at least as good as your known best. Your known best will only get better up to min(n, m) times total, so the best_possible increment will happen very rarely and almost all squares will be rejected in O(1) time.
best_possible = 0
for r in range(n):
for c in range(m):
while True:
# this looks O(min(n, m)), but it's amortized O(1) since best_possible
# rarely increased.
if possible(r, c, best_possible+1):
best_possible += 1
else:
break
Problem
I would like to know the different algorithms to find the biggest square in a two dimensions map dotted with obstacles. An example, where `o` would be obstacles: ``` ........................... ....o...................... ............o.............. ........................... ....o...................... ...............o........... ........................... ......o..............o..... ..o.......o................ ``` The biggest square would be (if we choose the first one): ``` .....xxxxxxx............... ....oxxxxxxx............... .....xxxxxxxo.............. .....xxxxxxx............... ....oxxxxxxx............... .....xxxxxxx...o........... .....xxxxxxx............... ......o..............o..... ..o.......o................ ``` What would be the fastest algorithm to find it? The one with the smallest complexity? EDIT: I know that people are interested on the algorithm explained in the accepted answer, so I made a document that explains it a bit more, you can find it here: https://docs.google.com/document/d/19pHCD433tYsvAor0WObxa2qusAjKdx96kaf3z5I8XT8/edit?usp=sharing