Given a binary matrix of size n * m, find out the maximum size of square sub-matrix with all 1s.
This algorithm uses memoization to improve performance. It's same as the recursive version of Maximum size of square sub-matrix with all 1s, but with a special 'cache' to store results. The 'cache key' is crucial. It's how we identify and store past results. Sometimes we need one key, sometimes multiple keys. We add code to:
cache = None
def search(m, i, j, mx):
if i < 0 or i >= len(m) or j < 0 or j >= len(m[0]):
return 0
global cache
if not cache:
cache = [[None] * len(m[0]) for _ in range(len(m))]
if not cache[i][j]:
right = search(m, i, j + 1, mx)
down = search(m, i + 1, j, mx)
diagonal = search(m, i + 1, j + 1, mx)
if m[i][j] == 0:
cache[i][j] = 0
else:
val = 1 + min(right, down, diagonal)
mx[0] = max(mx[0], val)
cache[i][j] = val
return cache[i][j]
data = [
[0, 1, 1, 0, 1],
[1, 1, 0, 1, 0],
[0, 1, 1, 1, 0],
[1, 1, 1, 1, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0]
]
mx = [0]
search(data, 0, 0, mx)
print(mx[0])
let cache = null;
function search(m, i, j, max) {
if (i < 0 || i >= m.length || j < 0 || j >= m[0].length) {
return 0;
}
if (!cache) {
cache = Array.from(Array(m.length), () => Array(m[0].length).fill(null));
}
if (!cache[i][j]) {
let right = search(m, i, j + 1, max);
let down = search(m, i + 1, j, max);
let diagonal = search(m, i + 1, j + 1, max);
if (m[i][j] === 0) {
cache[i][j] = 0;
} else {
const val = 1 + Math.min(right, down, diagonal);
max[0] = Math.max(max[0], val);
m[i][j] = val;
}
}
return m[i][j];
}
const data = [
[0, 1, 1, 0, 1],
[1, 1, 0, 1, 0],
[0, 1, 1, 1, 0],
[1, 1, 1, 1, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0]
];
let max = [0];
search(data, 0, 0, max);
console.log(max[0]);