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: aaabb
Output: ababa
Input: aa
Output: Not Possible
Input: aaaabc
Output: Not Possible
Asked In: Amazon Interview
To solve the problem using this approach follow the below idea:
The idea is to put the highest frequency character first (a greedy approach). Use a priority queue (Or Binary Max Heap) and put all characters and ordered by their frequencies (highest frequency character at root). One by one take the highest frequency character from the heap and add it to result. After adding it, just decrease the frequency of the character and then temporarily move this character out of priority queue so that it is not picked again next time.
Follow the given steps to solve the problem:
- Build a Priority_queue or max_heap, pq that stores characters with their frequencies.
- Priority_queue or max_heap is built on the basis of the frequency of character.
- Create a temporary Key that will be used as the previously visited element (the previous element in the resultant string. Initialize it { char = ‘#’ , freq = ‘-1’ }
- While pq is not empty.
- Pop an element and add it to the result.
- Decrease the frequency of the popped element by ‘1’
- Push the previous element back into the priority_queue if its frequency is greater than zero.
- Make the current element as the previous element for the next iteration.
- If the length of the resultant string and the original string is not equal, then print “not possible”, else print the resultant string.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 26;
struct Key {
int freq;
char ch;
bool operator<( const Key& k) const
{
return freq < k.freq;
}
};
void rearrangeString(string str)
{
int N = str.length();
int count[MAX_CHAR] = { 0 };
for ( int i = 0; i < N; i++)
count[str[i] - 'a' ]++;
priority_queue<Key> pq;
for ( char c = 'a' ; c <= 'z' ; c++) {
int val = c - 'a' ;
if (count[val]) {
pq.push(Key{ count[val], c });
}
}
str = "" ;
Key prev{ -1, '#' };
while (!pq.empty()) {
Key k = pq.top();
pq.pop();
str = str + k.ch;
if (prev.freq > 0)
pq.push(prev);
(k.freq)--;
prev = k;
}
if (N != str.length())
cout << " Not possible " << endl;
else
cout << str << endl;
}
int main()
{
string str = "bbbaa" ;
rearrangeString(str);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class KeyComparator implements Comparator<Key> {
public int compare(Key k1, Key k2)
{
if (k1.freq < k2.freq)
return 1 ;
else if (k1.freq > k2.freq)
return - 1 ;
return 0 ;
}
}
class Key {
int freq;
char ch;
Key( int val, char c)
{
freq = val;
ch = c;
}
}
class GFG {
static int MAX_CHAR = 26 ;
static void rearrangeString(String str)
{
int n = str.length();
int [] count = new int [MAX_CHAR];
for ( int i = 0 ; i < n; i++)
count[str.charAt(i) - 'a' ]++;
PriorityQueue<Key> pq
= new PriorityQueue<>( new KeyComparator());
for ( char c = 'a' ; c <= 'z' ; c++) {
int val = c - 'a' ;
if (count[val] > 0 )
pq.add( new Key(count[val], c));
}
str = "" ;
Key prev = new Key(- 1 , '#' );
while (pq.size() != 0 ) {
Key k = pq.peek();
pq.poll();
str = str + k.ch;
if (prev.freq > 0 )
pq.add(prev);
(k.freq)--;
prev = k;
}
if (n != str.length())
System.out.println( " Not possible " );
else
System.out.println(str);
}
public static void main(String args[])
{
String str = "bbbaa" ;
rearrangeString(str);
}
}
|
C#
using System;
public class GFG
{
const int MAX_CHAR = 26;
public struct Key
{
public int freq;
public char ch;
public int CompareTo(Key other)
{
return freq - other.freq;
}
};
public static void rearrangeString(String str)
{
int N = str.Length;
int [] count = new int [MAX_CHAR];
for ( int i = 0; i < N; i++)
count[str[i] - 'a' ]++;
PriorityQueue<Key> pq = new PriorityQueue<Key>();
for ( int c = 'a' ; c <= 'z' ; c++)
{
int val = c - 'a' ;
if (count[val] > 0)
pq.Enqueue( new Key(count[val], ( char )c));
}
str = "" ;
Key prev = new Key(-1, '#' );
while (pq.Count != 0)
{
Key k = pq.Dequeue();
str += k.ch;
if (prev.freq > 0)
pq.Enqueue(prev);
(k.freq)--;
prev = k;
}
if (N != str.Length)
Console.WriteLine( " Not possible " );
else
Console.WriteLine(str);
}
public static void Main()
{
String str = "bbbaa" ;
rearrangeString(str);
}
}
|
Javascript
const MAX_CHAR = 26;
const rearrangeString = (str) => {
let N = str.length;
let count = Array(MAX_CHAR).fill(0);
for (let i = 0; i < N; i++) {
count[str.charCodeAt(i) - 'a' .charCodeAt(0)]++;
}
let pq = [];
for (let c = 'a' ; c <= 'z' ; c++) {
let val = c.charCodeAt(0) - 'a' .charCodeAt(0);
if (count[val]) {
pq.push({ freq: count[val], ch: c });
}
}
str = "" ;
let prev = { freq: -1, ch: ' #' };
while (pq.length > 0) {
let k = pq.shift();
str = str + k.ch;
if (prev.freq > 0) pq.push(prev);
k.freq--;
prev = k;
}
if (N != str.length) {
console.log( " Not possible " );
} else {
console.log(str);
}
};
|
Python3
from heapq import heappush, heappop
from collections import Counter
class Key:
def __init__( self , character: str , freq: int ) - > None :
self .character = character
self .freq = freq
def __lt__( self , other: "Key" ) - > bool :
return self .freq > other.freq
def rearrangeString( str : str ):
n = len ( str )
count = dict ()
for i in str :
count[ ord (i)] = count.get( ord (i), 0 ) + 1
pq = []
for c in range ( 97 , 123 ):
if count.get(c, 0 ):
heappush(pq, Key( chr (c), count))
prev = Key( '#' , - 1 )
str = ""
while pq:
key = heappop(pq)
str + = key.character
key.freq - = 1
if prev.freq > 0 :
heappush(pq, prev)
prev = key
if len ( str ) ! = n:
print ( "Not possible" )
else :
print ( str )
if __name__ = = "__main__" :
string = "bbbaa"
rearrangeString(string)
|
Time complexity : O(N log(N))
Auxiliary Space: O(N), Extra space is used to store the resultant string
Rearrange characters in a String such that no two adjacent characters are same using Frequency:
To solve the problem using this approach follow the below idea:
Fill all the even positions of the result string first, with the highest frequency character. If there are still some even positions remaining, fill them first. Once even positions are done, then fill the odd positions. This way, it can be ensured that no two adjacent characters are the same.
Follow the given steps to solve the problem:
- Calculate the frequencies of every character in the input string
- If a character with a maximum frequency has a frequency greater than (n + 1) / 2, then return an empty string, as it is not possible to construct a string
- Now fill the even index positions with the maximum frequency character, if some even positions are remaining then first fill them with remaining characters
- Then fill odd index positions with the remaining characters
- Return the constructed string
Below is the implementation of the above approach:
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char getMaxCountChar( int count[])
{
int max = 0;
char ch;
for ( int i = 0; i < 26; i++) {
if (count[i] > max) {
max = count[i];
ch = 'a' + i;
}
}
return ch;
}
char * rearrangeString( char S[])
{
int N = strlen (S);
if (N == 0)
return "" ;
int count[26] = { 0 };
for ( int i = 0; i < N; i++)
count[S[i] - 'a' ]++;
char ch_max = getMaxCountChar(count);
int maxCount = count[ch_max - 'a' ];
char * res = malloc (N * sizeof ( int ));
int ind = 0;
if (maxCount > (N + 1) / 2)
return res;
while (maxCount) {
res[ind] = ch_max;
ind = ind + 2;
maxCount--;
}
count[ch_max - 'a' ] = 0;
for ( int i = 0; i < 26; i++) {
while (count[i] > 0) {
ind = (ind >= N) ? 1 : ind;
res[ind] = 'a' + i;
ind += 2;
count[i]--;
}
}
return res;
}
int main()
{
char str[] = { "bbbaa" };
char * res = rearrangeString(str);
if (res == "" )
printf ( "Not possible \n" );
else
printf ( "%s \n" , res);
return 0;
}
|
Java
import java.io.*;
class GFG {
static char getMaxCountChar( int [] count)
{
int max = 0 ;
char ch = 0 ;
for ( int i = 0 ; i < 26 ; i++) {
if (count[i] > max) {
max = count[i];
ch = ( char )(( int ) 'a' + i);
}
}
return ch;
}
static String rearrangeString(String S)
{
int N = S.length();
if (N == 0 )
return "" ;
int [] count = new int [ 26 ];
for ( int i = 0 ; i < 26 ; i++) {
count[i] = 0 ;
}
for ( char ch : S.toCharArray()) {
count[( int )ch - ( int ) 'a' ]++;
}
char ch_max = getMaxCountChar(count);
int maxCount = count[( int )ch_max - ( int ) 'a' ];
if (maxCount > (N + 1 ) / 2 )
return "" ;
String res = "" ;
for ( int i = 0 ; i < N; i++) {
res += ' ' ;
}
int ind = 0 ;
while (maxCount > 0 ) {
res = res.substring( 0 , ind) + ch_max
+ res.substring(ind + 1 );
ind = ind + 2 ;
maxCount--;
}
count[( int )ch_max - ( int ) 'a' ] = 0 ;
for ( int i = 0 ; i < 26 ; i++) {
while (count[i] > 0 ) {
ind = (ind >= N) ? 1 : ind;
res = res.substring( 0 , ind)
+ ( char )(( int ) 'a' + i)
+ res.substring(ind + 1 );
ind += 2 ;
count[i]--;
}
}
return res;
}
public static void main(String args[])
{
String str = "bbbaa" ;
String res = rearrangeString(str);
if (res == "" )
System.out.println( "Not possible" );
else
System.out.println(res);
}
}
|
C#
using System;
public class GFG
{
const int MAX_CHAR = 26;
public struct Key
{
public int freq;
public char ch;
public int CompareTo(Key other)
{
return freq - other.freq;
}
};
public static void rearrangeString(String str)
{
int N = str.Length;
int [] count = new int [MAX_CHAR];
for ( int i = 0; i < N; i++)
count[str[i] - 'a' ]++;
PriorityQueue<Key> pq = new PriorityQueue<Key>();
for ( int c = 'a' ; c <= 'z' ; c++)
{
int val = c - 'a' ;
if (count[val] > 0)
pq.Enqueue( new Key(count[val], ( char )c));
}
str = "" ;
Key prev = new Key(-1, '#' );
while (pq.Count != 0)
{
Key k = pq.Dequeue();
str += k.ch;
if (prev.freq > 0)
pq.Enqueue(prev);
(k.freq)--;
prev = k;
}
if (N != str.Length)
Console.WriteLine( " Not possible " );
else
Console.WriteLine(str);
}
public static void Main()
{
String str = "bbbaa" ;
rearrangeString(str);
}
}
|
Javascript
function getMaxCountChar(count){
let maxCount = 0
let maxChar
for (let i = 0; i < 26; i++){
if (count[i] > maxCount){
maxCount = count[i]
maxChar = String.fromCharCode(i + ( 'a' ).charCodeAt(0))
}
}
return [maxCount, maxChar]
}
function rearrangeString(S){
let n = S.length
if (!n)
return false
let count = new Array(26).fill(0)
for (let char of S)
count[char.charCodeAt(0) - ( 'a' ).charCodeAt(0)] += 1
let [maxCount, maxChar] = getMaxCountChar(count)
if (maxCount > Math.floor((n + 1) / 2))
return false
let res = new Array(n)
let ind = 0
while (maxCount){
res[ind] = maxChar
ind += 2
maxCount -= 1
}
count[maxChar.charCodeAt(0) - 'a' .charCodeAt(0)] = 0
for (let i = 0; i < 26; i++)
{
while (count[i] > 0)
{
if (ind >= n)
ind = 1
res[ind] = String.fromCharCode(i + ( 'a' ).charCodeAt(0))
ind += 2
count[i] -= 1
}
}
return res.join( '' )
}
let str = 'bbbaa'
let res = rearrangeString(str)
if (res)
document.write(res)
else
document.write( 'Not valid string' )
|
C++14
#include <bits/stdc++.h>
using namespace std;
char getMaxCountChar(vector< int >& count)
{
int max = 0;
char ch;
for ( int i = 0; i < 26; i++) {
if (count[i] > max) {
max = count[i];
ch = 'a' + i;
}
}
return ch;
}
string rearrangeString(string S)
{
int N = S.size();
if (N == 0)
return "" ;
vector< int > count(26, 0);
for ( auto & ch : S)
count[ch - 'a' ]++;
char ch_max = getMaxCountChar(count);
int maxCount = count[ch_max - 'a' ];
if (maxCount > (n + 1) / 2)
return "" ;
string res(n, ' ' );
int ind = 0;
while (maxCount) {
res[ind] = ch_max;
ind = ind + 2;
maxCount--;
}
count[ch_max - 'a' ] = 0;
for ( int i = 0; i < 26; i++) {
while (count[i] > 0) {
ind = (ind >= n) ? 1 : ind;
res[ind] = 'a' + i;
ind += 2;
count[i]--;
}
}
return res;
}
int main()
{
string str = "bbbaa" ;
string res = rearrangeString(str);
if (res == "" )
cout << "Not possible" << endl;
else
cout << res << endl;
return 0;
}
|
Python3
from heapq import heappush, heappop
from collections import Counter
class Key:
def __init__( self , character: str , freq: int ) - > None :
self .character = character
self .freq = freq
def __lt__( self , other: "Key" ) - > bool :
return self .freq > other.freq
def rearrangeString(s: str ):
n = len (s)
count = Counter(s)
pq = []
for c, freq in count.items():
heappush(pq, Key(c, freq))
prev = Key( '#' , - 1 )
result = []
while pq:
key = heappop(pq)
result.append(key.character)
key.freq - = 1
if prev.freq > 0 :
heappush(pq, prev)
prev = key
if len (result) ! = n:
print ( "Not possible" )
else :
print ("".join(result))
if __name__ = = "__main__" :
string = "bbbaa"
rearrangeString(string)
|
Time complexity: O(N)
Auxiliary Space: O(N+26), as there are 26 lowercase english characters
Last Updated :
01 Mar, 2024
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...