class Solution(object): def countSquares(self, matrix): """ :type matrix: List[List[int]] :rtype: int """ ROWS, COLS = len(matrix), len(matrix[0]) cache = {} def dfs(r, c): # base case if r == ROWS or c == COLS or matrix[r][c] == 0: return 0 if (r, c) in cache: return cache[(r, c)] cache[(r, c)] = 1 + min( dfs(r, c + 1), dfs(r + 1, c), dfs(r + 1, c + 1) ) return cache[(r, c)] res = 0 for r in range(ROWS): for c in range(COLS): res += dfs(r, c) return res
Explanation
Given an array like this, the tip to solving this problem is checking the minimum square that can be created from each point.
Let’s use the bottom right 1 as an example. We’ll check the right, down and diagonal point relative to the 1 and see the minimum square that can be created.
right: 0
bottom: 0
diagonal: 0
We return 1 because just the 1 can be made into a square
We then do this for every element except for 0.
The base case is if the row or col goes out of bounds or if the current element is a 0: return
Ideally, we want to cache our results to save time.
This is done by adding the (r, c): length to the dict if they aren’t already in there.