Rearrange the given string such that all prime multiple indexes have same character

• Last Updated : 04 Jul, 2019

Given a string str of size N. The task is to find out whether it is possible to rearrange characters in string str so that for any prime number p <= N and for any integer i ranging from 1 to N/p the condition strp = strp*i must be satisfied. If it is not possible to for any such rearrangement then print -1.

Examples:

Input : str = “aabaaaa”
Output : baaaaaa
Size of the string is 7.
Indexes 2, 4, 6 contains same character.
Indexes 3, 6 contains the same character.

Input : str = “abcd”
Output : -1

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach:

• All positions except the first and those whose number is a prime greater N/2 must have the same symbol.
• Remaining positions can have any symbol. This positions kept using the sieve.
• If the most occurred element in the string is less than these positions then print -1.

Below is the implementation of the above approach:

C++

 // CPP program to rearrange the given // string such that all prime multiple// indexes have same character#include using namespace std;#define N 100005  // To store answerchar ans[N];int sieve[N];  // Function to rearrange the given string// such that all prime multiple indexes// have the same character.void Rearrange(string s, int n){    // Initially assume that we can kept    // any symbol at any positions.    // If at any index contains one then it is not    // counted in our required positions    fill(sieve + 1, sieve + n + 1, 1);      // To store number of positions required    // to store elements of same kind    int sz = 0;      // Start sieve    for (int i = 2; i <= n / 2; i++) {        if (sieve[i]) {            // For all multiples of i            for (int j = 1; i * j <= n; j++) {                if (sieve[i * j])                    sz++;                sieve[i * j] = 0;            }        }    }      // map to store frequency of each character    map m;    for (auto it : s)        m[it]++;      // Store all characters in the vector and    // sort the vector to find the character with    // highest frequency    vector > v;    for (auto it : m)        v.push_back({ it.second, it.first });    sort(v.begin(), v.end());      // If most occured character is less than    // required positions    if (v.back().first < sz) {        cout << -1;        return;    }      // In all required positions keep    // character which occured most times    for (int i = 2; i <= n; i++) {        if (!sieve[i]) {              ans[i] = v.back().second;        }    }      // Fill all other indexes with    // remaining characters    int idx = 0;    for (int i = 1; i <= n; i++) {        if (sieve[i]) {            ans[i] = v[idx].second;            v[idx].first--;            // If character frequency becomes            // zero then go to next character            if (v[idx].first == 0)                idx++;        }        cout << ans[i];    }}  // Driver codeint main(){    string str = "aabaaaa";      int n = str.size();      // Function call    Rearrange(str, n);      return 0;}

Python3

 # Python3 program to rearrange the given # string such that all prime multiple # indexes have same character   N = 100005  # To store answer ans = *N; # sieve = *N;   # Function to rearrange the given string # such that all prime multiple indexes # have the same character. def Rearrange(s, n) :       # Initially assume that we can kept     # any symbol at any positions.     # If at any index contains one then it is not     # counted in our required positions     sieve = *(N+1);          # To store number of positions required     # to store elements of same kind    sz = 0;          # Start sieve    for i in range(2, n//2 + 1) :        if (sieve[i]) :                          # For all multiples of i            for j in range(1, n//i + 1) :                if (sieve[i * j]) :                    sz += 1;                sieve[i * j] = 0;                      # map to store frequency of each character     m = dict.fromkeys(s,0);          for it in s :        m[it] += 1;              # Store all characters in the vector and     # sort the vector to find the character with     # highest frequency    v = [];    for key,value in m.items() :        v.append([ value, key] );          v.sort();          # If most occured character is less than    # required positions    if (v[-1] < sz) :        print(-1,end="");        return;              # In all required positions keep    # character which occured most times    for i in range(2, n + 1) :        if (not sieve[i]) :            ans[i] = v[-1];                  # Fill all other indexes with     # remaining characters     idx = 0;          for i in range(1, n + 1) :        if (sieve[i]):            ans[i] = v[idx];            v[idx] -= 1;                          # If character frequency becomes             # zero then go to next character            if (v[idx] == 0) :                idx += 1;                          print(ans[i],end= "");                     # Driver code if __name__ == "__main__" :       string = "aabaaaa";       n = len(string);       # Function call     Rearrange(string, n);   # This code is contributed by AnkitRai01
Output:
baaaaaa

My Personal Notes arrow_drop_up