Open In App

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

Last Updated : 08 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  1. Let the given string be str and size of string be n and alphabet size is be assumed as 256 (a constant).
  2. We scan input string str and store frequencies of all characters in an array freq.
  3. 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.
  4. 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.

Following is the implementation of above algorithm. 

C++




// C++ program to rearrange a string so that all same
// characters become atleast d distance away
#include <bits/stdc++.h>
#define MAX_CHAR 256
using namespace std;
 
// The function returns next eligible character
// with maximum frequency (Greedy!!) and
// zero or negative distance
int 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 away
int 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 code
int 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




// Java program to rearrange a string so that all same
// characters become atleast d distance away
import java.util.*;
 
class GFG
{
 
static int MAX_CHAR = 256;
 
// The function returns next eligible character
// with maximum frequency (Greedy!!) and
// zero or negative distance
static 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 away
static 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 code
public 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




# Python3 program to rearrange a string so that all
# same characters become at least d distance away
MAX_CHAR = 256
 
# The function returns next eligible character
# with maximum frequency (Greedy!!)
# and zero or negative distance
def 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 away
def 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 code
if __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#




// C# program to rearrange a string so that all same
// characters become atleast d distance away
using System;
     
class GFG
{
 
static int MAX_CHAR = 256;
 
// The function returns next eligible character
// with maximum frequency (Greedy!!) and
// zero or negative distance
static 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 away
static 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 code
public 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


Javascript




<script>
 
// Javascript program to rearrange a
// string so that all same characters
// become atleast d distance away
let MAX_CHAR = 256;
 
// The function returns next eligible
// character with maximum frequency
// (Greedy!!) and zero or negative distance
function 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 away
function 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 code
let str= "aaaabbbcc".split("");
let n = str.length;
 
// To store output
let 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

Time Complexity : O(N* MAX_CHAR) , here N is length of string

Space Complexity : O(N)



Similar Reads

Rearrange a string so that all same characters become d distance away
Given a string and a positive integer d. Some characters may be repeated in the given string. Rearrange characters of the given string such that the same characters become 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,
14 min read
Find the path from root to a vertex such that all K vertices belongs to this path or 1 distance away
Given a tree consisting of N vertices numbered from 1 to N rooted at vertex 1. You are given Q queries. Each query consists of the set of K distinct vertices vi[1], vi[2],…, vi[K]. The task is to determine if there is a path from the root to some vertex X such that each of the given K vertices either belongs to this path or has the distance 1 to so
10 min read
Rearrange string such that characters at same distance from start and end are different
Given a string S of length N, rearrange the characters of the string such that for every index i &lt; N / 2, S[i] != S[N-i-1]. Print -1 if it is impossible to form such a string. Note: If there are multiple possible answers, print any one of them. Examples: Input: S = "aabbcc"Output: "aacbcb"Explanation: "aacbcb" is a perfect palindromic string as
8 min read
Rearrange Linked List to make XOR of nodes at same distance from start and end same
Given a linked list containing N nodes of binary numbers, the task is to check whether it is possible to rearrange the linked list in such a way that value of XOR between element at ith Node and N+1−ith node is the same for all 1 ≤ i ≤ N. Print Yes, if the Linked List can be rearranged, or else print No. Examples: Input: LL = 0 -&gt; 0 -&gt; 1Outpu
8 min read
Rearrange characters in a sorted string such that no pair of adjacent characters are the same
Given a sorted string S consisting of N lowercase characters, the task is to rearrange characters in the given string such that no two adjacent characters are the same. If it is not possible to rearrange as per the given criteria, then print "-1". Examples: Input: S = "aaabc"Output: abaca Input: S = "aa"Output: -1 Approach: The given problem can be
20 min read
Rearrange characters in a String such that no two adjacent characters are same
Given a string with lowercase repeated characters, the task is to rearrange characters in a string so that no two adjacent characters are the same. If it is not possible to do so, then print "Not possible". Examples: Input: aaabc Output: abaca Input: aaabbOutput: ababa Input: aa Output: Not Possible Input: aaaabc Output: Not Possible Asked In: Amaz
18 min read
Number of Positions to partition the string such that atleast m characters with same frequency are present in each substring
Given a string str of lowercase English alphabets and an integer m. The task is to count how many positions are there in the string such that if you partition the string into two non-empty sub-strings, there are at least m characters with the same frequency in both sub-strings. The characters need to be present in the string str.Examples: Input: st
16 min read
Check if all the set bits of the binary representation of N are at least K places away
Given numbers N and K, The task is to check if all the set bits of the binary representation of N are at least K places away. Examples: Input: N = 5, K = 1 Output: YES Explanation: Binary of 5 is 101. The 1's are 1 place far from each other. Input: N = 10, K = 2 Output: NO Explanation: Binary of 10 is 1010. The 1's are not at least 2 places far fro
6 min read
Check if frequency of all characters can become same by one removal
Given a string that contains lower alphabetic characters, we need to remove at most one character from this string in such a way that frequency of each distinct character becomes the same in the string. Examples:   Input: str = “xyyz” Output: Yes We can remove character ’y’ from above string to make the frequency of each character same.  Input: str
21 min read
Rearrange characters in a string such that no two adjacent are same using hashing
Given a string str with repeated characters, the task is to rearrange the characters in a string such that no two adjacent characters are the same. If it is possible then print Yes else print No. Examples: Input: str = "geeksforgeeks" Output: Yes "egeksforegeks" is one such arrangement. Input: str = "bbbbb" Output: No Approach: The idea is to store
5 min read
Article Tags :
Practice Tags :