Rearrange a string so that all same characters become atleast d distance away - GeeksforGeeks

12 Jun, 2021
Given a string and a positive integer d, rearrange characters of the given string such that the same characters become at-least d distance away from each other.
Note that there can be many possible rearrangements, the output should be one of the possible rearrangements. If no such arrangement is possible, that should also be reported.
Expected time complexity is O(n) where n is length of input string.
Examples: 
Input:  "aaaabbbcc", d = 2
Output: "ababacabc" 

Input:  "aacbbc", d = 3
Output: "abcabc" 

Input: "geeksforgeeks", d = 3
Output: egkesfegkeors

Input:  "aaa",  d = 2
Output: Cannot be rearranged 
We have already discussed how to put same characters exactly d distance away. This is a extended version where same characters should be moved at-least d distance away.
The idea is to use extra space to store frequencies of all characters and maintain an array for inserting the values at correct distance. Following is the complete algorithm – 
Let the given string be str and size of string be n and alphabet size is be assumed as 256 (a constant).We scan input string str and store frequencies of all characters in an array freq.We create an array dist[] for inserting the values at correct distance. dist[j] will store the least distance between current position and the next position we can use character ‘j’. If dist[j] <= 0, character ‘j’ can be inserted in current position.run a loop n times Search for next eligible character with maximum frequency and dist[j] <= 0.If we found such character, we put that character at next available position in output array, decrease its frequency and reset its distance as d. If we don’t find any character, string cannot be rearranged and we return false.As we move forward in output string, we decrement distance of all characters in dist[] by 1.
Let the given string be str and size of string be n and alphabet size is be assumed as 256 (a constant).
We scan input string str and store frequencies of all characters in an array freq.
We create an array dist[] for inserting the values at correct distance. dist[j] will store the least distance between current position and the next position we can use character ‘j’. If dist[j] <= 0, character ‘j’ can be inserted in current position.
run a loop n times Search for next eligible character with maximum frequency and dist[j] <= 0.If we found such character, we put that character at next available position in output array, decrease its frequency and reset its distance as d. If we don’t find any character, string cannot be rearranged and we return false.As we move forward in output string, we decrement distance of all characters in dist[] by 1.
Search for next eligible character with maximum frequency and dist[j] <= 0.
If we found such character, we put that character at next available position in output array, decrease its frequency and reset its distance as d. If we don’t find any character, string cannot be rearranged and we return false.
As we move forward in output string, we decrement distance of all characters in dist[] by 1.
Following is the implementation of above algorithm. 
C++
Java
Python3
C#
Javascript
// C++ program to rearrange a string so that all same// characters become atleast d distance away#include <bits/stdc++.h>#define MAX_CHAR 256using namespace std; // The function returns next eligible character// with maximum frequency (Greedy!!) and// zero or negative distanceint nextChar(int freq[], int dist[]){    int max = INT_MIN;    for (int i = 0; i < MAX_CHAR; i++)        if (dist[i] <= 0 && freq[i] > 0 &&        (max == INT_MIN || freq[i] > freq[max]))                max = i;     return max;} // The main function that rearranges input string 'str'// such that two same characters become atleast d// distance awayint rearrange(char str[], char out[], int d){    // Find length of input string    int n = strlen(str);     // Create an array to store all characters and their    // frequencies in str[]    int freq[MAX_CHAR] = { 0 };     // Traverse the input string and store frequencies    // of all characters in freq[] array.    for (int i = 0; i < n; i++)        freq[str[i]]++;     // Create an array for inserting the values at    // correct distance dist[j] stores the least distance    // between current position and the next position we    // can use character 'j'    int dist[MAX_CHAR] = { 0 };     for (int i = 0; i < n; i++)    {        // find next eligible character        int j = nextChar(freq, dist);         // return 0 if string cannot be rearranged        if (j == INT_MIN)            return 0;         // Put character j at next position        out[i] = j;         // decrease its frequency        freq[j]--;         // set distance as d        dist[j] = d;         // decrease distance of all characters by 1        for (int i = 0; i < MAX_CHAR; i++)            dist[i]--;    }     // null terminate output string    out[n] = '\0';     // return success    return 1;} // Driver codeint main(){    char str[] = "aaaabbbcc";    int n = strlen(str);     // To store output    char out[n];     if (rearrange(str, out, 2))        cout << out;    else        cout << "Cannot be rearranged";     return 0;}
// Java program to rearrange a string so that all same// characters become atleast d distance awayimport java.util.*; class GFG{ static int MAX_CHAR = 256; // The function returns next eligible character// with maximum frequency (Greedy!!) and// zero or negative distancestatic int nextChar(int freq[], int dist[]){    int max = Integer.MIN_VALUE;    for (int i = 0; i < MAX_CHAR; i++)        if (dist[i] <= 0 && freq[i] > 0 &&        (max == Integer.MIN_VALUE || freq[i] > freq[max]))                max = i;     return max;} // The main function that rearranges input string 'str'// such that two same characters become atleast d// distance awaystatic int rearrange(char str[], char out[], int d){    // Find length of input string    int n = str.length;     // Create an array to store all characters and their    // frequencies in str[]    int []freq = new int[MAX_CHAR];     // Traverse the input string and store frequencies    // of all characters in freq[] array.    for (int i = 0; i < n; i++)        freq[str[i]]++;     // Create an array for inserting the values at    // correct distance dist[j] stores the least distance    // between current position and the next position we    // can use character 'j'    int []dist = new int[MAX_CHAR];     for (int i = 0; i < n; i++)    {        // find next eligible character        int j = nextChar(freq, dist);         // return 0 if string cannot be rearranged        if (j == Integer.MIN_VALUE)            return 0;         // Put character j at next position        out[i] = (char) j;         // decrease its frequency        freq[j]--;         // set distance as d        dist[j] = d;         // decrease distance of all characters by 1        for (int k = 0; k < MAX_CHAR; k++)            dist[k]--;    }     // null terminate output string        Arrays.copyOfRange(out, 0, n);    // out[n] = '\0';     // return success    return 1;} // Driver codepublic static void main(String[] args){    char str[] = "aaaabbbcc".toCharArray();    int n = str.length;     // To store output    char []out = new char[n];     if (rearrange(str, out, 2)==1)            System.out.println(String.valueOf(out));    else            System.out.println("Cannot be rearranged");}} // This code is contributed by Rajput-Ji
# Python3 program to rearrange a string so that all# same characters become at least d distance awayMAX_CHAR = 256 # The function returns next eligible character# with maximum frequency (Greedy!!)# and zero or negative distancedef nextChar(freq, dist):     Max = float('-inf')    for i in range(0, MAX_CHAR):        if (dist[i] <= 0 and freq[i] > 0 and        (Max == float('-inf') or freq[i] > freq[Max])):                Max = i     return Max # The main function that rearranges input# string 'str' such that two same characters# become atleast d distance awaydef rearrange(string, out, d):     # Find length of input string    n = len(string)     # Create an array to store all characters    # and their frequencies in str[]    freq = [0] * MAX_CHAR     # Traverse the input string and store frequencies    # of all characters in freq[] array.    for i in range(0, n):        freq[ord(string[i])] += 1     # Create an array for inserting the values at    # correct distance dist[j] stores the least    # distance between current position and the    # we next position can use character 'j'    dist = [0] * MAX_CHAR     for i in range(0, n):             # find next eligible character        j = nextChar(freq, dist)         # return 0 if string cannot be rearranged        if j == float('-inf'):            return 0         # Put character j at next position        out[i] = chr(j)         # decrease its frequency        freq[j] -= 1         # set distance as d        dist[j] = d         # decrease distance of all characters by 1        for i in range(0, MAX_CHAR):            dist[i] -= 1     # return success    return 1 # Driver codeif __name__ == "__main__":     string = "aaaabbbcc"    n = len(string)     # To store output    out = [None] * n     if rearrange(string, out, 2):        print(''.join(out))    else:        print("Cannot be rearranged") # This code is contributed by Rituraj Jain
// C# program to rearrange a string so that all same// characters become atleast d distance awayusing System;     class GFG{ static int MAX_CHAR = 256; // The function returns next eligible character// with maximum frequency (Greedy!!) and// zero or negative distancestatic int nextChar(int []freq, int []dist){    int max = int.MinValue;    for (int i = 0; i < MAX_CHAR; i++)        if (dist[i] <= 0 && freq[i] > 0 &&        (max == int.MinValue || freq[i] > freq[max]))                max = i;     return max;} // The main function that rearranges input string 'str'// such that two same characters become atleast d// distance awaystatic int rearrange(char []str, char []ouT, int d){    // Find length of input string    int n = str.Length;     // Create an array to store all characters and their    // frequencies in str[]    int []freq = new int[MAX_CHAR];     // Traverse the input string and store frequencies    // of all characters in freq[] array.    for (int i = 0; i < n; i++)        freq[str[i]]++;     // Create an array for inserting the values at    // correct distance dist[j] stores the least distance    // between current position and the next position we    // can use character 'j'    int []dist = new int[MAX_CHAR];     for (int i = 0; i < n; i++)    {        // find next eligible character        int j = nextChar(freq, dist);         // return 0 if string cannot be rearranged        if (j == int.MinValue)            return 0;         // Put character j at next position        ouT[i] = (char) j;         // decrease its frequency        freq[j]--;         // set distance as d        dist[j] = d;         // decrease distance of all characters by 1        for (int k = 0; k < MAX_CHAR; k++)            dist[k]--;    }     // null terminate output string        Array.Copy(ouT,ouT, n);    // out[n] = '\0';     // return success    return 1;} // Driver codepublic static void Main(String[] args){    char []str = "aaaabbbcc".ToCharArray();    int n = str.Length;     // To store output    char []ouT = new char[n];     if (rearrange(str, ouT, 2)==1)            Console.WriteLine(String.Join("",ouT));    else            Console.WriteLine("Cannot be rearranged");}} // This code is contributed by 29AjayKumar
<script> // Javascript program to rearrange a// string so that all same characters// become atleast d distance awaylet MAX_CHAR = 256; // The function returns next eligible// character with maximum frequency// (Greedy!!) and zero or negative distancefunction nextChar(freq, dist){    let max = Number.MIN_VALUE;    for(let i = 0; i < MAX_CHAR; i++)        if (dist[i] <= 0 && freq[i] > 0 &&           (max == Number.MIN_VALUE ||            freq[i] > freq[max]))            max = i;       return max;} // The main function that rearranges input// string 'str' such that two same characters// become atleast d distance awayfunction rearrange(str, out, d){         // Find length of input string    let n = str.length;       // Create an array to store all characters    // and their frequencies in str[]    let freq = new Array(MAX_CHAR);      for(let i = 0; i < freq.length; i++)    {        freq[i] = 0;    }         // Traverse the input string and store    // frequencies of all characters in    // freq[] array.    for(let i = 0; i < n; i++)        freq[str[i].charCodeAt(0)]++;       // Create an array for inserting the    // values at correct distance dist[j]    // stores the least distance between    // current position and the next position    // we can use character 'j'    let dist = new Array(MAX_CHAR);      for(let i = 0; i < dist.length; i++)    {        dist[i] = 0;    }    for(let i = 0; i < n; i++)    {                 // Find next eligible character        let j = nextChar(freq, dist);           // return 0 if string cannot        // be rearranged        if (j == Number.MIN_VALUE)            return 0;           // Put character j at next position        out[i] = String.fromCharCode (j);           // Decrease its frequency        freq[j]--;           // Set distance as d        dist[j] = d;           // Decrease distance of all        // characters by 1        for(let k = 0; k < MAX_CHAR; k++)            dist[k]--;    }       // Null terminate output string    // Arrays.copyOfRange(out, 0, n);    // out[n] = '\0';       // Return success    return 1;} // Driver codelet str= "aaaabbbcc".split("");let n = str.length; // To store outputlet out = new Array(n); if (rearrange(str, out, 2) == 1)    document.write(out.join(""));else    document.write("Cannot be rearranged"); // This code is contributed by rag2127 </script>
Output : 
ababacabc
This article is contributed by Aditya Goel. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
rituraj_jain
Rajput-Ji
29AjayKumar
rag2127
Strings
Strings
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Top 50 String Coding Problems for Interviews
Vigenère Cipher
How to Append a Character to a String in C
Program to add two binary strings
Convert character array to string in C++
Return maximum occurring character in an input string
Naive algorithm for Pattern Searching
Hill Cipher
sprintf() in C
A Program to check if strings are rotations of each other or not