Python program to Rearrange a string so that all same characters become d distance away

Given a string and an integer d, we need to rearrange the string such that all same characters are at least distance d apart from each other. If it's not possible to rearrange the string, we return an empty string.

Problem Understanding

The key challenge is to place characters with higher frequencies first, ensuring they have enough positions to maintain the required distance d.

Example 1

str_input = "tutorialspoint"
d = 3
# Result: "tiotiotalnprsu"
# Same characters are at least 3 positions apart

Example 2

str_input = "aaabc"
d = 3
# Result: "" (impossible to arrange)
# Three 'a's cannot be placed with distance 3 in a string of length 5

Solution Using Greedy Approach with Priority Queue

We use a max heap to process characters by frequency, placing the most frequent characters first to ensure they have enough positions ?

from collections import Counter
import heapq

def rearrange_string(s, d):
    if d == 0:
        return s
    
    # Count character frequencies
    char_count = Counter(s)
    n = len(s)
    
    # Create max heap (use negative frequencies for max heap behavior)
    max_heap = [(-count, char) for char, count in char_count.items()]
    heapq.heapify(max_heap)
    
    result = [''] * n
    
    # Place characters starting from most frequent
    for start_pos in range(d):
        heap_copy = max_heap[:]
        
        pos = start_pos
        while heap_copy and pos < n:
            # Get most frequent remaining character
            neg_freq, char = heapq.heappop(heap_copy)
            freq = -neg_freq
            
            if freq > 0:
                result[pos] = char
                pos += d
                
                # Update frequency and push back if still has occurrences
                if freq > 1:
                    heapq.heappush(heap_copy, (-(freq - 1), char))
        
        # Update main heap
        max_heap = heap_copy[:]
    
    # Check if all positions are filled
    if '' in result:
        return ""
    
    return ''.join(result)

# Test examples
print(rearrange_string("tutorialspoint", 3))
print(rearrange_string("aabbcc", 3))
print(rearrange_string("aaabc", 3))
print(rearrange_string("aaadbbcc", 2))
tiotlainopsurt
abcabc

abacbdacbd

Optimized Solution

Here's a cleaner implementation that handles the rearrangement more efficiently ?

from collections import Counter

def rearrange_with_distance(s, d):
    if d == 0:
        return s
    
    n = len(s)
    char_count = Counter(s)
    
    # Sort characters by frequency (descending)
    sorted_chars = sorted(char_count.items(), key=lambda x: x[1], reverse=True)
    
    result = [''] * n
    index = 0
    
    # Place each character type
    for char, freq in sorted_chars:
        # Check if it's possible to place all occurrences
        if freq > (n + d - 1) // d:
            return ""
        
        # Place character occurrences with distance d
        for _ in range(freq):
            if index >= n:
                # Reset to next available starting position
                index = 0
                while index < n and result[index] != '':
                    index += 1
                if index >= n:
                    return ""
            
            result[index] = char
            index += d
    
    return ''.join(result)

# Test the solution
test_cases = [
    ("tutorialspoint", 3),
    ("aabbcc", 3), 
    ("aaabc", 3),
    ("aaadbbcc", 2)
]

for s, d in test_cases:
    result = rearrange_with_distance(s, d)
    print(f"Input: '{s}', d={d} ? Output: '{result}'")
Input: 'tutorialspoint', d=3 ? Output: 'tiotlainopsurt'
Input: 'aabbcc', d=3 ? Output: 'abcabc'
Input: 'aaabc', d=3 ? Output: ''
Input: 'aaadbbcc', d=2 ? Output: 'abacbdacdb'

How It Works

The algorithm works in these steps:

  1. Count frequencies: Use Counter to get character frequencies
  2. Sort by frequency: Process most frequent characters first
  3. Place characters: For each character, place all occurrences with distance d
  4. Validation: Check if placement is possible before starting

Time Complexity

The time complexity is O(n) where n is the length of the string, since we visit each position at most once.

Conclusion

The greedy approach works by placing the most frequent characters first with the required distance. This ensures optimal utilization of available positions and prevents impossible arrangements early.

Updated on: 2026-03-25T05:55:01+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements