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);
}
}
|
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)
|
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);
}
};
|
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;
}
|
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;
}
|
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);
}
}
|
Python3
def getMaxCountChar(count):
maxCount = 0
for i in range ( 26 ):
if count[i] > maxCount:
maxCount = count[i]
maxChar = chr (i + ord ( 'a' ))
return maxCount, maxChar
def rearrangeString(S):
N = len (S)
if not N:
return False
count = [ 0 ] * 26
for char in S:
count[ ord (char) - ord ( 'a' )] + = 1
maxCount, maxChar = getMaxCountChar(count)
if maxCount > (N + 1 ) / / 2 :
return False
res = [ None ] * N
ind = 0
while maxCount:
res[ind] = maxChar
ind + = 2
maxCount - = 1
count[ ord (maxChar) - ord ( 'a' )] = 0
for i in range ( 26 ):
while count[i] > 0 :
if ind > = N:
ind = 1
res[ind] = chr (i + ord ( 'a' ))
ind + = 2
count[i] - = 1
return ''.join(res)
if __name__ = = '__main__' :
str = 'bbbaa'
res = rearrangeString( str )
if res:
print (res)
else :
print ( 'Not possible' )
|
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' )
|
Time complexity: O(N)
Auxiliary Space: O(N+26), as there are 26 lowercase english characters
This article is contributed by Nishant Singh . If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or 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.