Rearrange a string so that all same characters become atleast d distance away
Last Updated :
08 Mar, 2023
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.
Following is the implementation of above algorithm.
C++
#include <bits/stdc++.h>
#define MAX_CHAR 256
using namespace std;
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;
}
int rearrange( char str[], char out[], int d)
{
int n = strlen (str);
int freq[MAX_CHAR] = { 0 };
for ( int i = 0; i < n; i++)
freq[str[i]]++;
int dist[MAX_CHAR] = { 0 };
for ( int i = 0; i < n; i++)
{
int j = nextChar(freq, dist);
if (j == INT_MIN)
return 0;
out[i] = j;
freq[j]--;
dist[j] = d;
for ( int i = 0; i < MAX_CHAR; i++)
dist[i]--;
}
out[n] = '\0' ;
return 1;
}
int main()
{
char str[] = "aaaabbbcc" ;
int n = strlen (str);
char out[n];
if (rearrange(str, out, 2))
cout << out;
else
cout << "Cannot be rearranged" ;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int MAX_CHAR = 256 ;
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;
}
static int rearrange( char str[], char out[], int d)
{
int n = str.length;
int []freq = new int [MAX_CHAR];
for ( int i = 0 ; i < n; i++)
freq[str[i]]++;
int []dist = new int [MAX_CHAR];
for ( int i = 0 ; i < n; i++)
{
int j = nextChar(freq, dist);
if (j == Integer.MIN_VALUE)
return 0 ;
out[i] = ( char ) j;
freq[j]--;
dist[j] = d;
for ( int k = 0 ; k < MAX_CHAR; k++)
dist[k]--;
}
Arrays.copyOfRange(out, 0 , n);
return 1 ;
}
public static void main(String[] args)
{
char str[] = "aaaabbbcc" .toCharArray();
int n = str.length;
char []out = new char [n];
if (rearrange(str, out, 2 )== 1 )
System.out.println(String.valueOf(out));
else
System.out.println( "Cannot be rearranged" );
}
}
|
Python3
MAX_CHAR = 256
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
def rearrange(string, out, d):
n = len (string)
freq = [ 0 ] * MAX_CHAR
for i in range ( 0 , n):
freq[ ord (string[i])] + = 1
dist = [ 0 ] * MAX_CHAR
for i in range ( 0 , n):
j = nextChar(freq, dist)
if j = = float ( '-inf' ):
return 0
out[i] = chr (j)
freq[j] - = 1
dist[j] = d
for i in range ( 0 , MAX_CHAR):
dist[i] - = 1
return 1
if __name__ = = "__main__" :
string = "aaaabbbcc"
n = len (string)
out = [ None ] * n
if rearrange(string, out, 2 ):
print (''.join(out))
else :
print ( "Cannot be rearranged" )
|
C#
using System;
class GFG
{
static int MAX_CHAR = 256;
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;
}
static int rearrange( char []str, char []ouT, int d)
{
int n = str.Length;
int []freq = new int [MAX_CHAR];
for ( int i = 0; i < n; i++)
freq[str[i]]++;
int []dist = new int [MAX_CHAR];
for ( int i = 0; i < n; i++)
{
int j = nextChar(freq, dist);
if (j == int .MinValue)
return 0;
ouT[i] = ( char ) j;
freq[j]--;
dist[j] = d;
for ( int k = 0; k < MAX_CHAR; k++)
dist[k]--;
}
Array.Copy(ouT,ouT, n);
return 1;
}
public static void Main(String[] args)
{
char []str = "aaaabbbcc" .ToCharArray();
int n = str.Length;
char []ouT = new char [n];
if (rearrange(str, ouT, 2)==1)
Console.WriteLine(String.Join( "" ,ouT));
else
Console.WriteLine( "Cannot be rearranged" );
}
}
|
Javascript
<script>
let MAX_CHAR = 256;
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;
}
function rearrange(str, out, d)
{
let n = str.length;
let freq = new Array(MAX_CHAR);
for (let i = 0; i < freq.length; i++)
{
freq[i] = 0;
}
for (let i = 0; i < n; i++)
freq[str[i].charCodeAt(0)]++;
let dist = new Array(MAX_CHAR);
for (let i = 0; i < dist.length; i++)
{
dist[i] = 0;
}
for (let i = 0; i < n; i++)
{
let j = nextChar(freq, dist);
if (j == Number.MIN_VALUE)
return 0;
out[i] = String.fromCharCode (j);
freq[j]--;
dist[j] = d;
for (let k = 0; k < MAX_CHAR; k++)
dist[k]--;
}
return 1;
}
let str= "aaaabbbcc" .split( "" );
let n = str.length;
let out = new Array(n);
if (rearrange(str, out, 2) == 1)
document.write(out.join( "" ));
else
document.write( "Cannot be rearranged" );
</script>
|
Time Complexity : O(N* MAX_CHAR) , here N is length of string
Space Complexity : O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...