Rearrange a string so that all same characters become d distance away
Last Updated :
23 Jul, 2025
Given a string s and a positive integer d, rearrange the characters of the string so that any two identical characters are at least d positions apart. If no such arrangement is possible, print "Cannot be rearranged".
Examples:
Input: s="abb", d = 2
Output: "bab"
Explanation: The character 'a' and 'b' need to be rearranged such that 'b' appears at least 2 positions away from the other 'b'. One valid solution is "bab", where the two 'b's are at positions 2 and 3, satisfying the distance requirement.
Input: s="aacbbc", d = 3
Output: "abcabc"
Explanation: The characters are rearranged so that each pair of identical characters ('a', 'b', 'c') are placed at least 3 positions apart. One valid solution is "abcabc".
Input: s="geeksforgeeks", d = 3
Output: "egkegkesfesor"
Explanation: The characters are rearranged such that identical characters are at least 3 positions apart. One valid solution is "egkegkesfesor".
Input: s="aaa", d = 2
Output: "Cannot be rearranged"
Explanation: It's impossible to rearrange the characters of the string such that 'a' appears more than once and still respects the required distance of 2.
[Naive Approach] Checking all permutations - O(n! * n^2) time and O(n) space
The idea is to generate all permutations of the string and checks each one to see if identical characters are at least d positions apart. It guarantees finding a solution if it exists but is inefficient due to the factorial growth of permutations (n!).
C++
#include <bits/stdc++.h>
using namespace std;
// Function to check if all identical characters are at least d positions apart
bool valid(const string &s, int d) {
for (int i = 0; i < s.length(); i++) {
for (int j = i + 1; j < s.length(); j++) {
// Check if characters are the same and too close to each other
if (s[i] == s[j] && abs(i - j) < d) {
return false;
}
}
}
return true;
}
bool rearrange(string s, int d) {
// Sort the string to start with the lexicographically smallest permutation
sort(s.begin(), s.end());
// Try all permutations of the string
do {
// For each permutation, check if it satisfies the condition
if (valid(s, d)) {
// If valid, print the arrangement and return true
cout << s << endl;
return true;
}
} while (next_permutation(s.begin(), s.end())); // Generate next permutation
// If no valid arrangement is found, print a message and return false
cout << "Cannot be rearranged" << endl;
return false;
}
int main() {
string s="aabbcc";
int d=3;
rearrange(s, d);
return 0;
}
Java
import java.util.*;
public class GfG{
// Function to check if all identical characters are at least d positions apart
static boolean valid(String s, int d) {
for (int i = 0; i < s.length(); i++) {
for (int j = i + 1; j < s.length(); j++) {
// Check if characters are the same and too close to each other
if (s.charAt(i) == s.charAt(j) && Math.abs(i - j) < d) {
return false;
}
}
}
return true;
}
static boolean rearrange(String s, int d) {
// Convert string to character array and sort
char[] arr = s.toCharArray();
Arrays.sort(arr);
s = new String(arr);
// Try all permutations of the string
do {
// For each permutation, check if it satisfies the condition
if (valid(s, d)) {
// If valid, print the arrangement and return true
System.out.println(s);
return true;
}
} while ((s = nextPermutation(s)) != null);
// If no valid arrangement is found, print a message and return false
System.out.println("Cannot be rearranged");
return false;
}
static String nextPermutation(String s) {
char[] arr = s.toCharArray();
int i = arr.length - 1;
while (i > 0 && arr[i - 1] >= arr[i]) i--;
if (i <= 0) return null;
int j = arr.length - 1;
while (arr[j] <= arr[i - 1]) j--;
char temp = arr[i - 1];
arr[i - 1] = arr[j];
arr[j] = temp;
j = arr.length - 1;
while (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
return new String(arr);
}
public static void main(String[] args) {
String s = "aabbcc";
int d = 3;
rearrange(s, d);
}
}
Python
# Function to check if all identical characters are at least d positions apart
def valid(s, d):
for i in range(len(s)):
for j in range(i + 1, len(s)):
# Check if characters are the same and too close to each other
if s[i] == s[j] and abs(i - j) < d:
return False
return True
from itertools import permutations
def rearrange(s, d):
# Sort the string to start with the lexicographically smallest permutation
s = ''.join(sorted(s))
# Try all permutations of the string
for perm in permutations(s):
# For each permutation, check if it satisfies the condition
if valid(perm, d):
# If valid, print the arrangement and return true
print(''.join(perm))
return True
# If no valid arrangement is found, print a message and return false
print("Cannot be rearranged")
return False
s = "aabbcc"
d = 3
rearrange(s, d)
C#
using System;
using System.Linq;
class Program {
// Function to check if all identical characters are at least d positions apart
static bool Valid(string s, int d) {
for (int i = 0; i < s.Length; i++) {
for (int j = i + 1; j < s.Length; j++) {
// Check if characters are the same and too close to each other
if (s[i] == s[j] && Math.Abs(i - j) < d) {
return false;
}
}
}
return true;
}
static bool Rearrange(string s, int d) {
// Sort the string to start with the lexicographically smallest permutation
char[] arr = s.ToCharArray();
Array.Sort(arr);
s = new string(arr);
// Try all permutations of the string
do {
// For each permutation, check if it satisfies the condition
if (Valid(s, d)) {
// If valid, print the arrangement and return true
Console.WriteLine(s);
return true;
}
} while ((s = NextPermutation(s)) != null);
// If no valid arrangement is found, print a message and return false
Console.WriteLine("Cannot be rearranged");
return false;
}
static string NextPermutation(string s) {
char[] arr = s.ToCharArray();
int i = arr.Length - 1;
while (i > 0 && arr[i - 1] >= arr[i]) i--;
if (i <= 0) return null;
int j = arr.Length - 1;
while (arr[j] <= arr[i - 1]) j--;
char temp = arr[i - 1];
arr[i - 1] = arr[j];
arr[j] = temp;
j = arr.Length - 1;
while (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
return new string(arr);
}
static void Main() {
string s = "aabbcc";
int d = 3;
Rearrange(s, d);
}
}
JavaScript
// Function to check if all identical characters are at least d positions apart
function valid(s, d) {
for (let i = 0; i < s.length; i++) {
for (let j = i + 1; j < s.length; j++) {
// Check if characters are the same and too close to each other
if (s[i] === s[j] && Math.abs(i - j) < d) {
return false;
}
}
}
return true;
}
function rearrange(s, d) {
// Sort the string to start with the lexicographically smallest permutation
s = s.split('').sort().join('');
let found = false; // Flag to track if a valid arrangement is found
// Try all permutations of the string
const permute = (str, l, r) => {
if (l === r) {
// For each permutation, check if it satisfies the condition
if (valid(str, d)) {
// If valid, print the arrangement and return true
console.log(str);
found = true;
return true;
}
} else {
for (let i = l; i <= r; i++) {
str = swap(str, l, i);
if (permute(str, l + 1, r)) return true;
str = swap(str, l, i); // backtrack
}
}
return false;
};
const swap = (s, i, j) => {
const charArray = s.split('');
[charArray[i], charArray[j]] = [charArray[j], charArray[i]];
return charArray.join('');
};
// Start permuting
permute(s, 0, s.length - 1);
// If no valid arrangement found, print the failure message
if (!found) {
console.log("Cannot be rearranged");
}
}
const s = "aabbcc";
const d = 3;
rearrange(s, d);
Time Complexity: O(n! * n2), n! for generating all permutations
Auxiliary space : O(n)
[Expected Approach] Using Max Heap - O(n + m * log m) time and O(n) space
The idea is to use a greedy algorithm to place the most frequent characters first, ensuring identical characters are at least d positions apart. A max heap selects the frequent characters, and the string is filled by placing characters at intervals of d, maintaining the required distance. At any point, if we are not able to place, we return. At the end, if we are able to place all, we return the result string.
C++
#include <bits/stdc++.h>
using namespace std;
void rearrange(string s, int d) {
int n = s.size();
// Frequency map for characters
unordered_map<char, int> freq;
// Calculate frequencies of each character
for (int i = 0; i < n; i++) {
freq[s[i]]++;
s[i]='\0';
}
// Create a max heap
priority_queue<pair<int, char>,vector<pair<int,char>>,greater<pair<int,char>>> pq;
// Insert frequencies and characters into a max-heap
for (auto& entry : freq) {
pq.push({entry.second, entry.first});
}
// Rearrange characters in the string
while (!pq.empty()) {
char ch = pq.top().second;
int f = pq.top().first;
pq.pop();
// Find positions in the string and assign characters
int pos = 0;
while(s[pos]!='\0')
{
pos++;
}
while (f--) {
// If position exceeds the size of
// the string, cannot rearrange
if (pos >= n) {
cout << "Cannot be rearranged";
return;
}
s[pos] = ch;
pos += d;
}
}
cout << s;
}
int main() {
string s = "aabbcc";
rearrange(s, 3);
return 0;
}
Java
import java.util.*;
public class Rearrange {
public static void rearrange(String s, int d) {
int n = s.length();
// Frequency map for characters
Map<Character, Integer> freq = new HashMap<>();
for (char ch : s.toCharArray()) {
freq.put(ch, freq.getOrDefault(ch, 0) + 1);
}
// Max heap (sorting by frequency in descending order)
PriorityQueue<Map.Entry<Character, Integer>> pq =
new PriorityQueue<>((a, b) -> b.getValue() - a.getValue());
pq.addAll(freq.entrySet());
// Result array
char[] result = new char[n];
Arrays.fill(result, '\u0000');
// Queue to store delayed elements
Queue<Map.Entry<Character, Integer>> waitQueue = new LinkedList<>();
int index = 0;
while (!pq.isEmpty()) {
Map.Entry<Character, Integer> current = pq.poll();
char ch = current.getKey();
int count = current.getValue();
for (int i = 0; i < count; i++) {
// Find the next available position
while (index < n && result[index] != '\u0000') {
index++;
}
if (index >= n) {
System.out.println("Cannot be rearranged");
return;
}
result[index] = ch;
index += d; // Place next occurrence `d` positions apart
// If index exceeds n, reset it to the
// first available position
if (index >= n) {
index = 0;
while (index < n && result[index] != '\u0000') {
index++;
}
}
}
if (count > 1) {
waitQueue.add(new AbstractMap.SimpleEntry<>(ch, count - 1));
}
// After `d` iterations, reinsert from the waitQueue
if (waitQueue.size() >= d) {
pq.offer(waitQueue.poll());
}
}
System.out.println(new String(result));
}
public static void main(String[] args) {
String s = "aabbcc";
rearrange(s, 3);
}
}
Python
import heapq
def rearrange(s, d):
n = len(s)
# Frequency map for characters
freq = {}
# Calculate frequencies of each character
for char in s:
freq[char] = freq.get(char, 0) + 1
# Create a max heap (negative count for max heap behavior)
pq = [(-count, char) for char, count in freq.items()]
heapq.heapify(pq)
# Result array initialized with empty spaces
result = [''] * n
# List to store waiting characters
wait_queue = []
while pq:
count, ch = heapq.heappop(pq)
count = -count # Convert back to positive
# Find the first available position
pos = 0
while pos < n and result[pos] != '':
pos += 1
for _ in range(count):
if pos >= n:
print("Cannot be rearranged")
return
result[pos] = ch
pos += d
# After using this character, add to wait_queue
if count > 1:
wait_queue.append((count - 1, ch))
# If we have processed `d` elements, we can
# push back waiting elements
if len(wait_queue) >= d:
heapq.heappush(pq, (-wait_queue[0][0], wait_queue[0][1]))
wait_queue.pop(0)
print("".join(result))
# Example usage
s = "aabbcc"
rearrange(s, 3)
C#
using System;
using System.Linq;
using System.Collections.Generic;
class GFG
{
static void rearrange(char[] str, int d)
{
// Length of the string
int n = str.Length;
// A structure to store a character and its frequency
Dictionary<char, int> m = new Dictionary<char, int> ();
// Traverse the input string and store frequencies of
// all characters.
for (int i = 0; i < n; i++) {
if (!m.ContainsKey(str[i]))
m[str[i]] = 0;
m[str[i]]++;
str[i] = '\0';
}
// max-heap
List<Tuple<char, int>> pq = new List<Tuple<char, int>>();
foreach (var entry in m)
{
pq.Add(Tuple.Create(entry.Key, entry.Value));
}
pq = pq.OrderBy(a => a.Item2).ThenBy(a => a.Item1).ToList();
// Now one by one extract all distinct characters from
// heap and put them back in str[] with the d
// distance constraint
while (pq.Count > 0) {
char x = pq[0].Item1;
// Find the first available position in str[]
int p = 0;
while (str[p] != '\0')
p++;
// Fill x at p, p+d, p+2d, .. p+(frequency-1)d
for (int k = 0; k < pq[0].Item2; k++) {
// If the index goes beyond size, then string
// cannot be rearranged.
if (p + d * k >= n) {
Console.WriteLine ("Cannot be rearranged");
return;
}
str[p + d * k] = x;
}
pq.RemoveAt(0);
}
}
public static void Main(string[] args)
{
char[] str = "aabbcc".ToCharArray();
rearrange(str, 3);
Console.WriteLine(new string(str));
}
}
JavaScript
// Function to rearrange characters in a string
function rearrange(s, d) {
let n = s.length;
// Frequency map for characters
let freq = {};
// Calculate frequencies of each character
for (let char of s) {
freq[char] = (freq[char] || 0) + 1;
}
// Create a max heap
let pq = [];
// Insert frequencies and characters into a max-heap
for (let char in freq) {
pq.push([-freq[char], char]);
}
pq.sort();
// Rearrange characters in the string
let result = new Array(n).fill('');
while (pq.length > 0) {
let [count, ch] = pq.shift();
count = -count;
// Find positions in the string and assign characters
let pos = 0;
while (pos < n && result[pos] !== '') {
pos++;
}
for (let i = 0; i < count; i++) {
// If position exceeds the size of the
// string, cannot rearrange
if (pos >= n) {
console.log('Cannot be rearranged');
return;
}
result[pos] = ch;
pos += d;
}
}
console.log(result.join(''));
}
// Example usage
let s = 'aabbcc';
rearrange(s, 3);
Time Complexity: (n + m * log m), m is maximum number of distinct character in string
Auxiliary space : O(n)
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem