Program to count submatrices with all ones using Python

Given an m x n binary matrix, we need to count how many submatrices contain all ones. A submatrix is a contiguous rectangular area within the matrix.

So, if the input matrix is ?

1 0 1
0 1 1
0 1 1

Then the output will be 13 as there are 6 (1x1) matrices, 3 (2x1) matrices, 2 (1x2) matrices, 1 (3x1) matrix and 1 (2x2) matrix.

Algorithm Approach

We use dynamic programming to solve this efficiently ?

  • Create a DP matrix where dp[i][j] represents the height of consecutive 1s ending at position (i,j)

  • For each row, calculate all possible submatrices by considering different widths

  • Use the minimum height in each width range to determine valid submatrices

Step-by-Step Solution

Step 1: Build Height Matrix

def solve(matrix):
    m = len(matrix)
    n = len(matrix[0])
    
    # Create DP matrix to store heights
    dp = [[0] * n for _ in range(m)]
    
    # Fill the DP matrix
    for i in range(m):
        for j in range(n):
            if i == 0 and matrix[i][j]:
                dp[i][j] = 1
            elif matrix[i][j]:
                dp[i][j] = dp[i-1][j] + 1
    
    return dp

# Test with example matrix
matrix = [[1,0,1],[0,1,1],[0,1,1]]
height_matrix = solve(matrix)

print("Original Matrix:")
for row in matrix:
    print(row)
    
print("\nHeight Matrix:")
for row in height_matrix:
    print(row)
Original Matrix:
[1, 0, 1]
[0, 1, 1]
[0, 1, 1]

Height Matrix:
[1, 0, 1]
[0, 1, 2]
[0, 2, 3]

Step 2: Count All Submatrices

def count_submatrices(matrix):
    m = len(matrix)
    n = len(matrix[0])
    
    # Build height matrix
    dp = [[0] * n for _ in range(m)]
    for i in range(m):
        for j in range(n):
            if i == 0 and matrix[i][j]:
                dp[i][j] = 1
            elif matrix[i][j]:
                dp[i][j] = dp[i-1][j] + 1
    
    # Count submatrices
    total = 0
    for i in range(m):
        for j in range(n):
            for k in range(j+1, n+1):
                # Find minimum height in range [j, k)
                min_height = min(dp[i][j:k])
                total += min_height
    
    return total

# Test with example
matrix = [[1,0,1],[0,1,1],[0,1,1]]
result = count_submatrices(matrix)
print(f"Total submatrices with all ones: {result}")
Total submatrices with all ones: 13

How It Works

The algorithm works in two phases ?

  1. Height Calculation: For each cell, calculate how many consecutive 1s are above it (including itself)

  2. Submatrix Counting: For each row and starting column, try all possible widths and count rectangles using the minimum height in that range

1 0 1 0 1 1 0 1 1 Heights: dp[0] = [1, 0, 1] dp[1] = [0, 1, 2] dp[2] = [0, 2, 3] Example: 2x2 submatrix with all ones 0 1 2 0 1 2

Complete Solution

def count_submatrices_with_all_ones(matrix):
    """
    Count all submatrices containing only 1s in a binary matrix.
    
    Args:
        matrix: 2D list of 0s and 1s
    
    Returns:
        int: Total count of submatrices with all ones
    """
    if not matrix or not matrix[0]:
        return 0
    
    m, n = len(matrix), len(matrix[0])
    
    # Step 1: Build height matrix
    heights = [[0] * n for _ in range(m)]
    
    for i in range(m):
        for j in range(n):
            if matrix[i][j] == 1:
                if i == 0:
                    heights[i][j] = 1
                else:
                    heights[i][j] = heights[i-1][j] + 1
    
    # Step 2: Count submatrices
    total_count = 0
    
    for i in range(m):
        for j in range(n):
            for k in range(j+1, n+1):
                min_height = min(heights[i][j:k])
                total_count += min_height
    
    return total_count

# Test cases
test_matrices = [
    [[1,0,1],[0,1,1],[0,1,1]],
    [[1,1],[1,1]],
    [[1,1,1],[1,1,1]]
]

for i, matrix in enumerate(test_matrices, 1):
    result = count_submatrices_with_all_ones(matrix)
    print(f"Test {i}: {result} submatrices")
    for row in matrix:
        print(row)
    print()
Test 1: 13 submatrices
[1, 0, 1]
[0, 1, 1]
[0, 1, 1]

Test 2: 9 submatrices
[1, 1]
[1, 1]

Test 3: 21 submatrices
[1, 1, 1]
[1, 1, 1]

Time Complexity

  • Time: O(m × n²) − building heights is O(m×n), counting is O(m×n²)

  • Space: O(m × n) − for the heights matrix

Conclusion

This dynamic programming approach efficiently counts all submatrices containing only ones by first calculating consecutive heights, then using minimum heights to determine valid rectangular areas. The algorithm handles edge cases and provides optimal performance for binary matrix analysis.

Updated on: 2026-03-25T20:57:58+05:30

715 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements