Program to find minimum swaps to arrange a binary grid using Python

When working with binary matrices, we sometimes need to arrange rows so that all elements above the major diagonal are 0. This can be achieved by swapping adjacent rows. Let's explore how to find the minimum number of swaps required.

Problem Understanding

Given an n x n binary matrix, we need to swap adjacent rows to ensure all elements above the major diagonal are 0. If no solution exists, we return -1.

For example, with this matrix:

0 1 0
0 1 1
1 0 0

We need to rearrange it so that elements above the diagonal are all 0.

Algorithm Approach

The strategy involves:

  • Calculate how many trailing zeros each row has from the right
  • For each position, find a suitable row that can be placed there
  • Count swaps needed to move that row to the correct position

Implementation

def solve(matrix):
    n = len(matrix)
    # Calculate trailing zeros for each row
    trailing_zeros = [n] * n
    
    for i in range(n):
        for j in range(n-1, -1, -1):
            if matrix[i][j] == 1:
                trailing_zeros[i] = n - j - 1
                break
    
    total_swaps = 0
    
    for i in range(n):
        required_zeros = n - i - 1
        found = False
        
        # Find a row with enough trailing zeros
        for j in range(i, n):
            if trailing_zeros[j] >= required_zeros:
                total_swaps += j - i  # Count swaps needed
                found = True
                break
        
        if not found:
            return -1
        
        # Move the found row to position i
        trailing_zeros[i+1:j+1] = trailing_zeros[i:j]
    
    return total_swaps

# Test the function
matrix = [[0, 1, 0], [0, 1, 1], [1, 0, 0]]
result = solve(matrix)
print(f"Minimum swaps required: {result}")
Minimum swaps required: 2

How It Works

The algorithm works in two phases:

  1. Count trailing zeros: For each row, count consecutive zeros from the right side
  2. Greedy placement: For each diagonal position, find the first available row with sufficient trailing zeros

Step-by-Step Example

def solve_with_steps(matrix):
    n = len(matrix)
    print("Original matrix:")
    for row in matrix:
        print(row)
    
    # Calculate trailing zeros
    trailing_zeros = [n] * n
    for i in range(n):
        for j in range(n-1, -1, -1):
            if matrix[i][j] == 1:
                trailing_zeros[i] = n - j - 1
                break
    
    print(f"\nTrailing zeros for each row: {trailing_zeros}")
    
    total_swaps = 0
    for i in range(n):
        required = n - i - 1
        print(f"\nPosition {i} needs {required} trailing zeros")
        
        for j in range(i, n):
            if trailing_zeros[j] >= required:
                swaps = j - i
                total_swaps += swaps
                print(f"Found suitable row at index {j}, swaps needed: {swaps}")
                trailing_zeros[i+1:j+1] = trailing_zeros[i:j]
                break
    
    return total_swaps

matrix = [[0, 1, 0], [0, 1, 1], [1, 0, 0]]
result = solve_with_steps(matrix)
print(f"\nTotal minimum swaps: {result}")
Original matrix:
[0, 1, 0]
[0, 1, 1]
[1, 0, 0]

Trailing zeros for each row: [1, 0, 2]

Position 0 needs 2 trailing zeros
Found suitable row at index 2, swaps needed: 2

Position 1 needs 1 trailing zeros
Found suitable row at index 1, swaps needed: 0

Position 2 needs 0 trailing zeros
Found suitable row at index 2, swaps needed: 0

Total minimum swaps: 2

Conclusion

The algorithm efficiently finds the minimum swaps by using a greedy approach to place rows with sufficient trailing zeros. The time complexity is O(n²) and it returns -1 when no valid arrangement exists.

Updated on: 2026-03-25T21:01:12+05:30

387 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements