Number of square matrices with all 1s (original) (raw)
Given an **N*M matrix containing only 0s and 1s, the task is to count the number of square submatrices containing all 1s.
**Examples:
**Input: arr[][] = {{0, 1, 1, 1},
{1, 1, 1, 1},
{0, 1, 1, 1}}
**Output: 15
**Explanation:
There are 10 squares of side length 1.
There are 4 squares of side length 2.
There is 1 square of side length 3.
Total number of squares = 10 + 4 + 1 = 15.**Input: arr[][] = {{1, 1},
{1, 1},
{1, 1}}
**Output: 8
There are 6 squares of length 1
There are 2 squares of length 2**Input: arr[][] = {{1, 0, 1},
{1, 1, 0},
{1, 1, 0}}
**Output: 7
**Naive Recursion Approach:
- At every position, we determine the maximum possible side length for a square if we consider that position as the top left corner.
- Therefore, we can calculate the total number of squares as sum of these lengths
**How do we compute total numbers of squares that have arr[i][j] as the top left.
- If arr[i][j] is 0, we return 0 and do not proceed.
- We initialize res = 0
- If arr[i][j] is 1, then we add 1 to the result.
- Now we recursively compute number of squares where right or arr[i][j+1], below or arr[i+1][j] and below-right or arr[i+1][j+1] are individually top left corners. And take take the minimum of these 3 and add to the result. C++ `
#include <bits/stdc++.h> using namespace std;
// Function to solve the problem recursively int sqRec(vector<vector>& arr, int i, int j) { // Base case: if out of bounds or current element is 0 if (i < 0 or i >= arr.size() or j < 0 or j >= arr[0].size() or arr[i][j] == 0) return 0;
// Return the count of squares for the current position
return 1 + min({ sqRec(arr, i, j + 1), // Right
sqRec(arr, i + 1, j), // Below
sqRec(arr, i + 1, j + 1) }); // Below-Right}
// Function to return the number of square submatrices with all 1s int countSquarrs(vector<vector>& arr) { int res = 0;
// Iterate over each element of the matrix
for (int i = 0; i < arr.size(); i++) {
for (int j = 0; j < arr[0].size(); j++) {
if (arr[i][j] == 1) {
// If current element is 1, recursively
// calculate the number of squares and
// add it to the answer
res += sqRec(arr, i, j);
}
}
}
return res;}
// Driver code int main() { vector<vector> arr = { { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 0 } };
cout << countSquarrs(arr);
return 0;}
Java
import java.util.ArrayList; import java.util.List;
public class SquareSubmatrices { // Function to solve the problem recursively static int solve(List<List> matrix, int m, int n, int i, int j) { // Base case: if out of bounds or current element is 0 if (i < 0 || i >= m || j < 0 || j >= n || matrix.get(i).get(j) == 0) { return 0; }
// Recursive calls to calculate the number of squares in right, bottom, and bottom-right directions
int right = solve(matrix, m, n, i, j + 1);
int bottom = solve(matrix, m, n, i + 1, j);
int bottomRight = solve(matrix, m, n, i + 1, j + 1);
// Return the count of squares for the current position
return 1 + Math.min(Math.min(right, bottom), bottomRight);
}
// Function to return the number of square submatrices with all 1s
static int countSquareMatrices(List<List<Integer>> matrix) {
int m = matrix.size();
int n = matrix.get(0).size();
int ans = 0;
// Iterate over each element of the matrix
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix.get(i).get(j) == 1) {
// If current element is 1, recursively calculate the number of squares and add it to the answer
ans += solve(matrix, m, n, i, j);
}
}
}
// Return the final answer
return ans;
}
// Driver code
public static void main(String[] args) {
List<List<Integer>> arr = new ArrayList<>();
arr.add(List.of(1, 0, 1));
arr.add(List.of(1, 1, 0));
arr.add(List.of(1, 1, 0));
System.out.println(countSquareMatrices(arr));
}}
Python
def solve(matrix, m, n, i, j): # Base case: if out of bounds or current element is 0 if i < 0 or i >= m or j < 0 or j >= n or matrix[i][j] == 0: return 0
# Recursive calls to calculate the number of squares in right, bottom, and bottom-right directions
right = solve(matrix, m, n, i, j + 1)
bottom = solve(matrix, m, n, i + 1, j)
bottom_right = solve(matrix, m, n, i + 1, j + 1)
# Return the count of squares for the current position
return 1 + min(right, bottom, bottom_right)def countSquareMatrices(matrix): m = len(matrix) n = len(matrix[0]) ans = 0
# Iterate over each element of the matrix
for i in range(m):
for j in range(n):
if matrix[i][j] == 1:
# If current element is 1, recursively calculate the number of squares and add it to the answer
ans += solve(matrix, m, n, i, j)
# Return the final answer
return ansDriver code
arr = [[1, 0, 1], [1, 1, 0], [1, 1, 0]] print(countSquareMatrices(arr))
C#
using System; using System.Collections.Generic;
public class GFG { // Function to solve the problem recursively public static int Solve(List<List> matrix, int m, int n, int i, int j) { // Base case: if out of bounds or current element is 0 if (i < 0 || i >= m || j < 0 || j >= n || matrix[i][j] == 0) { return 0; }
// Recursive calls to calculate the number of squares in
// right, bottom, and bottom-right directions
int right = Solve(matrix, m, n, i, j + 1);
int bottom = Solve(matrix, m, n, i + 1, j);
int bottom_right = Solve(matrix, m, n, i + 1, j + 1);
// Return the count of squares for the current position
return 1 + Math.Min(Math.Min(right, bottom), bottom_right);
}
// Function to return the number of square submatrices with all 1s
public static int CountSquareMatrices(List<List<int>> matrix)
{
int m = matrix.Count;
int n = matrix[0].Count;
int ans = 0;
// Iterate over each element of the matrix
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (matrix[i][j] == 1)
{
// If current element is 1, recursively calculate
// the number of squares and add it to the answer
ans += Solve(matrix, m, n, i, j);
}
}
}
// Return the final answer
return ans;
}
// Driver code
public static void Main(string[] args)
{
List<List<int>> arr = new List<List<int>>()
{
new List<int>() { 1, 0, 1 },
new List<int>() { 1, 1, 0 },
new List<int>() { 1, 1, 0 }
};
Console.WriteLine(CountSquareMatrices(arr));
}}
JavaScript
`
**Time Complexity: Exponential
**Using Memoization:
There are overlapping subproblems as we make three calls for adjacent cells of every cell. So we can optimize the recursive solution. We make a 2D memo array to store the results of already computed subptoblems. We make it 2D because there are two parameters (i and j) that change in recursion. We make the size of memo as m x n because these parameters range from 0 to m-1 and 0 to n-1 respectively. We initialize the memo array as -1 to indiciate nothing is computed and before making a recursive call, we check if the value for the current position is already present in the memo.. If so, it directly returns that value instead of recomputing it.
C++ `
#include <bits/stdc++.h> using namespace std;
// Function to solve the problem recursively with memoization int sqRec(vector<vector>& arr, int i, int j, vector<vector>& memo) {
// Base case: if out of bounds or current element is 0
if (i < 0 or i >= arr.size() or
j < 0 or j >= arr[j].size() or arr[i][j] == 0)
return 0;
// If the result is already computed, return it
if (memo[i][j] != -1)
return memo[i][j];
// Calculate the count of squares for the current position
// and store it in the memo array
memo[i][j] = 1 + min({ sqRec(arr, i, j + 1, memo), // Right
sqRec(arr, i + 1, j, memo), // Below
sqRec(arr, i + 1, j + 1, memo) }); // Below-Right
return memo[i][j];}
// Function to return the number of square submatrices with all 1s int countSquarrs(vector<vector>& arr) { int m = arr.size(); int n = arr[0].size(); int res = 0;
// Initialize memoization matrix with -1
vector<vector<int>> memo(m, vector<int>(n, -1));
// Iterate over each element of the matrix
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (arr[i][j] == 1) {
// If current element is 1, recursively calculate
// the number of squares and add it to the result
res += sqRec(arr, i, j, memo);
}
}
}
return res;}
// Driver code int main() { vector<vector> arr = { { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 0 } }; cout << countSquarrs(arr); return 0; }
Java
import java.util.*;
public class SquareSubmatrices { // Recursive function to solve the problem static int solve(int[][] matrix, int m, int n, int i, int j, int[][] dp) { // Base case: if out of bounds or current element is // 0 if (i < 0 || i >= m || j < 0 || j >= n || matrix[i][j] == 0) { return 0; }
// If the value is already calculated, return it
// from dp table
if (dp[i][j] != -1)
return dp[i][j];
// Recursive calls to calculate the number of
// squares in right, bottom, and bottom-right
// directions
int right = solve(matrix, m, n, i, j + 1, dp);
int bottom = solve(matrix, m, n, i + 1, j, dp);
int bottomRight
= solve(matrix, m, n, i + 1, j + 1, dp);
// Memoize the calculated value and return it
return dp[i][j]
= 1
+ Math.min(Math.min(right, bottom),
bottomRight);
}
// Function to return the number of square submatrices
// with all 1s
static int countSquareMatrices(int[][] matrix)
{
int m = matrix.length;
int n = matrix[0].length;
// Create a dp table to store the results of
// subproblems
int[][] dp = new int[m + 1][n + 1];
for (int[] row : dp) {
Arrays.fill(row, -1);
}
int ans = 0;
// Iterate over each element of the matrix
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 1) {
// If the current element is 1,
// recursively calculate the number of
// squares and add it to the answer
ans += solve(matrix, m, n, i, j, dp);
}
}
}
// Return the final answer
return ans;
}
// Driver code
public static void main(String[] args)
{
int[][] arr
= { { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 0 } };
System.out.println(countSquareMatrices(arr));
}}
Python
Recursive function to solve the problem
def solve(matrix, m, n, i, j, dp): # Base case: if out of bounds or current element is 0 if i < 0 or i >= m or j < 0 or j >= n or matrix[i][j] == 0: return 0
# If the value is already calculated, return it from dp table
if dp[i][j] != -1:
return dp[i][j]
# Recursive calls to calculate the number of squares in right, bottom, and bottom-right directions
right = solve(matrix, m, n, i, j + 1, dp)
bottom = solve(matrix, m, n, i + 1, j, dp)
bottom_right = solve(matrix, m, n, i + 1, j + 1, dp)
# Memoize the calculated value and return it
dp[i][j] = 1 + min(right, bottom, bottom_right)
return dp[i][j]Function to return the number of square submatrices with all 1s
def countSquareMatrices(matrix): m = len(matrix) n = len(matrix[0])
# Create a dp table to store the results of subproblems
dp = [[-1] * (n + 1) for _ in range(m + 1)]
ans = 0
# Iterate over each element of the matrix
for i in range(m):
for j in range(n):
if matrix[i][j] == 1:
# If the current element is 1, recursively calculate the number of squares and add it to the answer
ans += solve(matrix, m, n, i, j, dp)
# Return the final answer
return ansDriver code
arr = [[1, 0, 1], [1, 1, 0], [1, 1, 0]] print(countSquareMatrices(arr))
C#
using System;
public class GFG { // Recursive function to solve the problem public static int Solve(int[][] matrix, int m, int n, int i, int j, int[][] dp) { // Base case: if out of bounds or current element is 0 if (i < 0 || i >= m || j < 0 || j >= n || matrix[i][j] == 0) { return 0; }
// If the value is already calculated, return it from dp table
if (dp[i][j] != -1)
return dp[i][j];
// Recursive calls to calculate the number of squares in right,
// bottom, and bottom-right directions
int right = Solve(matrix, m, n, i, j + 1, dp);
int bottom = Solve(matrix, m, n, i + 1, j, dp);
int bottomRight = Solve(matrix, m, n, i + 1, j + 1, dp);
// Memoize the calculated value and return it
return dp[i][j] = 1 + Math.Min(right, Math.Min(bottom, bottomRight));
}
// Function to return the number of square submatrices with all 1s
public static int CountSquareMatrices(int[][] matrix)
{
int m = matrix.Length;
int n = matrix[0].Length;
// Create a dp table to store the results of subproblems
int[][] dp = new int[m + 1][];
for (int i = 0; i <= m; i++)
{
dp[i] = new int[n + 1];
for (int j = 0; j <= n; j++)
{
dp[i][j] = -1;
}
}
int ans = 0;
// Iterate over each element of the matrix
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (matrix[i][j] == 1)
{
// If the current element is 1, recursively
// calculate the number of squares and add it to the answer
ans += Solve(matrix, m, n, i, j, dp);
}
}
}
// Return the final answer
return ans;
}
// Driver code
public static void Main(string[] args)
{
int[][] arr = new int[][] {
new int[] { 1, 0, 1 },
new int[] { 1, 1, 0 },
new int[] { 1, 1, 0 }
};
Console.WriteLine(CountSquareMatrices(arr));
}}
JavaScript
// Recursive function to solve the problem function solve(matrix, m, n, i, j, dp) { // Base case: if out of bounds or current element is 0 if (i < 0 || i >= m || j < 0 || j >= n || matrix[i][j] === 0) { return 0; }
// If the value is already calculated, return it from dp table
if (dp[i][j] !== -1) {
return dp[i][j];
}
// Recursive calls to calculate the number of squares in
// right, bottom, and bottom-right directions
const right = solve(matrix, m, n, i, j + 1, dp);
const bottom = solve(matrix, m, n, i + 1, j, dp);
const bottomRight = solve(matrix, m, n, i + 1, j + 1, dp);
// Memoize the calculated value and return it
return (dp[i][j] = 1 + Math.min(right, bottom, bottomRight));}
// Function to return the number of square submatrices with all 1s function countSquareMatrices(matrix) { const m = matrix.length; const n = matrix[0].length;
// Create a dp table to store the results of subproblems
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(-1));
let ans = 0;
// Iterate over each element of the matrix
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (matrix[i][j] === 1) {
// If the current element is 1, recursively
// calculate the number of squares and add
// it to the answer
ans += solve(matrix, m, n, i, j, dp);
}
}
}
// Return the final answer
return ans;}
// Example usage const matrix = [ [1, 0, 1], [1, 1, 0], [1, 1, 0], ];
console.log(countSquareMatrices(matrix));
`
**Time Complexity: O(m x n)
**Auxiliary Space: O(1)
Using DP Buttom-Up:
This problem can be solved using Dynamic Programming.
- Let the array dp_[i][j]_ store the number of square matrices ending at _(i, j)_
- The recurrence relation to find the number of squares ending at ****(i, j)** can be given by:
- If dp[i][j] is 1:
* **dp[i][j] = min( min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1 - Else if arr[i][j] is 0:
* **dp[i][j] = 0
- If dp[i][j] is 1:
- Calculate the sum of the array which is equal to the number of square submatrices with all 1s.
Below is the implementation of the above approach:
CPP `
#include <bits/stdc++.h> using namespace std;
// Function to return the number of square submatrices with all 1s int countSquares(vector<vector>& arr) { int m = arr.size(); int n = arr[0].size();
// Create a dp array of the same size as the matrix
vector<vector<int>> dp(m, vector<int>(n, 0));
// Fill the first row (i = 0)
for (int j = 0; j < n; j++)
dp[0][j] = arr[0][j];
// Fill the first column (j = 0)
for (int i = 1; i < m; i++)
dp[i][0] = arr[i][0];
// Fill the rest of the dp array
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (arr[i][j] == 1) {
dp[i][j] = 1 + min({ dp[i - 1][j], // Top
dp[i][j - 1], // Left
dp[i - 1][j - 1] // Top-left diagonal
});
}
}
}
// Result is sum of all dp values
int res = 0;
for (int i=0; i<n; i++)
for (int j=0; j<m; j++)
res += dp[i][j];
return res;}
// Driver code int main() { vector<vector> arr = { { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 0 } }; cout << countSquares(arr);
return 0;}
Java
// Java program to return the number of // square submatrices with all 1s class GFG {
final static int n = 3;
final static int m = 3;
// Function to return the number of
// square submatrices with all 1s
static int countSquareMatrices(int a[][], int N, int M)
{
// Initialize count variable
int count = 0;
for (int i = 1; i < N; i++)
{
for (int j = 1; j < M; j++)
{
// If a[i][j] is equal to 0
if (a[i][j] == 0)
continue;
// Calculate number of
// square submatrices
// ending at (i, j)
a[i][j] = Math.min(Math.min(a[i - 1][j], a[i][j - 1]),
a[i - 1][j - 1]) + 1;
}
}
// Calculate the sum of the array
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
count += a[i][j];
return count;
}
// Driver code
public static void main (String[] args)
{
int arr[][] = { { 1, 0, 1 },
{ 1, 1, 0 },
{ 1, 1, 0 } };
System.out.println(countSquareMatrices(arr, n, m));
} }
// This code is contributed by AnkitRai01
Python
Python3 program to return the number of
square submatrices with all 1s
n = 3 m = 3
Function to return the number of
square submatrices with all 1s
def countSquareMatrices(a, N, M):
# Initialize count variable
count = 0
for i in range(1, N):
for j in range(1, M):
# If a[i][j] is equal to 0
if (a[i][j] == 0):
continue
# Calculate number of
# square submatrices
# ending at (i, j)
a[i][j] = min([a[i - 1][j],
a[i][j - 1], a[i - 1][j - 1]])+1
# Calculate the sum of the array
for i in range(N):
for j in range(M):
count += a[i][j]
return countDriver code
arr = [ [ 1, 0, 1], [ 1, 1, 0 ], [ 1, 1, 0 ] ]
print(countSquareMatrices(arr, n, m))
This code is contributed by mohit kumar 29
C#
// C# program to return the number of // square submatrices with all 1s using System;
class GFG {
static int n = 3;
static int m = 3;
// Function to return the number of
// square submatrices with all 1s
static int countSquareMatrices(int [,]a, int N, int M)
{
// Initialize count variable
int count = 0;
for (int i = 1; i < N; i++)
{
for (int j = 1; j < M; j++)
{
// If a[i][j] is equal to 0
if (a[i, j] == 0)
continue;
// Calculate number of
// square submatrices
// ending at (i, j)
a[i, j] = Math.Min(Math.Min(a[i - 1, j], a[i, j - 1]),
a[i - 1, j - 1]) + 1;
}
}
// Calculate the sum of the array
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
count += a[i, j];
return count;
}
// Driver code
public static void Main()
{
int [,]arr = { { 1, 0, 1 },
{ 1, 1, 0 },
{ 1, 1, 0 } };
Console.WriteLine(countSquareMatrices(arr, n, m));
} }
// This code is contributed by AnkitRai01
JavaScript
`
**Time Complexity: O(m x n)
**Auxiliary Space: O(1)