Program to find largest submatrix with rearrangements in Python

Given an m x n binary matrix, we can rearrange columns to find the largest submatrix containing only 1s. This problem combines dynamic programming with greedy optimization to maximize the area.

Problem Understanding

Consider this input matrix ?

0 0 1
1 1 1
1 0 1

After rearranging columns, we can get ?

1 1 0
1 1 1
0 1 1

The highlighted 2x2 submatrix has area 4, which is the maximum possible.

Algorithm Steps

The solution works in two phases ?

  • Phase 1: Calculate consecutive 1s in each column (histogram heights)
  • Phase 2: For each row, sort heights and find maximum rectangle area

Implementation

def solve(matrix):
    row, col = len(matrix), len(matrix[0])
    
    # Phase 1: Calculate consecutive 1s in each column
    for j in range(col):
        for i in range(1, row):
            if matrix[i][j]:
                matrix[i][j] += matrix[i-1][j]
    
    ans = 0
    # Phase 2: For each row, find max rectangle area
    for i in range(row):
        matrix[i].sort()  # Sort heights in ascending order
        for j in range(col-1, -1, -1):
            if matrix[i][j] == 0:
                break
            # Width = (col-j), Height = matrix[i][j]
            area = (col - j) * matrix[i][j]
            ans = max(ans, area)
    
    return ans

# Test with example
matrix = [[0, 0, 1], [1, 1, 1], [1, 0, 1]]
print("Maximum submatrix area:", solve(matrix))
Maximum submatrix area: 4

How It Works

Let's trace through the algorithm ?

def solve_with_trace(matrix):
    row, col = len(matrix), len(matrix[0])
    print("Original matrix:")
    for r in matrix:
        print(r)
    
    # Phase 1: Build histogram heights
    for j in range(col):
        for i in range(1, row):
            if matrix[i][j]:
                matrix[i][j] += matrix[i-1][j]
    
    print("\nAfter calculating consecutive 1s:")
    for r in matrix:
        print(r)
    
    ans = 0
    print("\nFinding maximum area for each row:")
    
    for i in range(row):
        original_row = matrix[i][:]
        matrix[i].sort()
        print(f"Row {i}: {original_row} -> sorted: {matrix[i]}")
        
        for j in range(col-1, -1, -1):
            if matrix[i][j] == 0:
                break
            area = (col - j) * matrix[i][j]
            print(f"  Width: {col-j}, Height: {matrix[i][j]}, Area: {area}")
            ans = max(ans, area)
    
    return ans

matrix = [[0, 0, 1], [1, 1, 1], [1, 0, 1]]
result = solve_with_trace(matrix)
print(f"\nMaximum area: {result}")
Original matrix:
[0, 0, 1]
[1, 1, 1]
[1, 0, 1]

After calculating consecutive 1s:
[0, 0, 1]
[1, 1, 2]
[2, 0, 3]

Finding maximum area for each row:
Row 0: [0, 0, 1] -> sorted: [0, 0, 1]
  Width: 1, Height: 1, Area: 1
Row 1: [1, 1, 2] -> sorted: [1, 1, 2]
  Width: 1, Height: 2, Area: 2
  Width: 2, Height: 1, Area: 2
  Width: 3, Height: 1, Area: 3
Row 2: [2, 0, 3] -> sorted: [0, 2, 3]
  Width: 1, Height: 3, Area: 3
  Width: 2, Height: 2, Area: 4

Maximum area: 4

Key Insights

  • Histogram approach: Each row represents a histogram where heights are consecutive 1s
  • Column rearrangement: Sorting heights allows optimal column positioning
  • Greedy selection: Largest heights are placed together for maximum area

Time and Space Complexity

Aspect Complexity Explanation
Time O(m × n × log n) Sorting each row takes O(n log n)
Space O(1) Modifies input matrix in-place

Conclusion

This algorithm efficiently finds the largest submatrix of 1s by treating each row as a histogram and using column rearrangement. The key insight is sorting heights to achieve optimal positioning for maximum rectangular area.

Updated on: 2026-03-26T14:27:10+05:30

376 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements