Open In App

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

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

Approach:

Below is the implementation of the above approach: 




// CPP program to rearrange the given
// string such that all prime multiple
// indexes have same character
#include <bits/stdc++.h>
using namespace std;
#define N 100005
 
// To store answer
char 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<char, int> 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<pair<int, char> > v;
    for (auto it : m)
        v.push_back({ it.second, it.first });
    sort(v.begin(), v.end());
 
    // If most occurred character is less than
    // required positions
    if (v.back().first < sz) {
        cout << -1;
        return;
    }
 
    // In all required positions keep
    // character which occurred 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 code
int main()
{
    string str = "aabaaaa";
 
    int n = str.size();
 
    // Function call
    Rearrange(str, n);
 
    return 0;
}




import java.util.*;
 
public class RearrangeString {
 
    static final int N = 100005;
    static char[] ans = new char[N];
    static int[] sieve = new int[N];
 
    // Function to rearrange the given string
    // such that all prime multiple indexes
    // have the same character.
    static void Rearrange(String s, int n) {
        // Initially assume that we can keep
        // any symbol at any positions.
        // If at any index contains one then it is not
        // counted in our required positions
        Arrays.fill(sieve, 1);
 
        // To store number of positions required
        // to store elements of the same kind
        int sz = 0;
 
        // Start sieve
        for (int i = 2; i <= n / 2; i++) {
            if (sieve[i] == 1) {
                // For all multiples of i
                for (int j = 1; i * j <= n; j++) {
                    if (sieve[i * j] == 1)
                        sz++;
                    sieve[i * j] = 0;
                }
            }
        }
 
        // map to store frequency of each character
        Map<Character, Integer> m = new HashMap<>();
        for (char c : s.toCharArray())
            m.put(c, m.getOrDefault(c, 0) + 1);
 
        // Store all characters in the vector and
        // sort the vector to find the character with
        // the highest frequency
        Vector<Pair> v = new Vector<>();
        for (Map.Entry<Character, Integer> entry : m.entrySet())
            v.add(new Pair(entry.getValue(), entry.getKey()));
        v.sort((a, b) -> Integer.compare(a.first, b.first));
 
        // If the most occurred character is less than
        // required positions
        if (v.lastElement().first < sz) {
            System.out.println(-1);
            return;
        }
 
        // In all required positions keep
        // a character that occurred the most times
        for (int i = 2; i <= n; i++) {
            if (sieve[i] == 0) {
                ans[i] = v.lastElement().second;
            }
        }
 
        // Fill all other indexes with
        // remaining characters
        int idx = 0;
        for (int i = 1; i <= n; i++) {
            if (sieve[i] == 1) {
                ans[i] = v.get(idx).second;
                v.get(idx).first--;
                // If character frequency becomes
                // zero then go to the next character
                if (v.get(idx).first == 0)
                    idx++;
            }
            System.out.print(ans[i]);
        }
    }
 
    // Driver code
    public static void main(String[] args) {
        String str = "aabaaaa";
        int n = str.length();
 
        // Function call
        Rearrange(str, n);
    }
 
    static class Pair {
        int first;
        char second;
 
        Pair(int first, char second) {
            this.first = first;
            this.second = second;
        }
    }
}




# Python3 program to rearrange the given
# string such that all prime multiple
# indexes have same character
 
N = 100005
 
# To store answer
ans = [0]*N;
# sieve = [1]*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 = [1]*(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 occurred character is less than
    # required positions
    if (v[-1][0] < sz) :
        print(-1,end="");
        return;
         
    # In all required positions keep
    # character which occurred most times
    for i in range(2, n + 1) :
        if (not sieve[i]) :
            ans[i] = v[-1][1];
             
    # Fill all other indexes with
    # remaining characters
    idx = 0;
     
    for i in range(1, n + 1) :
        if (sieve[i]):
            ans[i] = v[idx][1];
            v[idx][0] -= 1;
             
            # If character frequency becomes
            # zero then go to next character
            if (v[idx][0] == 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




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    const int N = 100005;
 
    // To store answer
    static char[] ans = new char[N];
    static int[] sieve = new int[N];
 
    // Function to rearrange the given string
    // such that all prime multiple indexes
    // have the same character.
    static void Rearrange(string s, int n)
    {
        // Initially assume that we can keep
        // any symbol at any positions.
        // If at any index contains one then it is not
        // counted in our required positions
        Array.Fill(sieve, 1, 1, n);
 
        // To store the number of positions required
        // to store elements of the same kind
        int sz = 0;
 
        // Start sieve
        for (int i = 2; i <= n / 2; i++)
        {
            if (sieve[i] == 1)
            {
                // For all multiples of i
                for (int j = 1; i * j <= n; j++)
                {
                    if (sieve[i * j] == 1)
                        sz++;
                    sieve[i * j] = 0;
                }
            }
        }
 
        // Dictionary to store the frequency of each character
        Dictionary<char, int> m = new Dictionary<char, int>();
        foreach (char c in s)
        {
            if (m.ContainsKey(c))
                m++;
            else
                m = 1;
        }
 
        // Store all characters in the list and
        // sort the list to find the character with
        // the highest frequency
        List<Tuple<int, char>> v = new List<Tuple<int, char>>();
        foreach (var kvp in m)
        {
            v.Add(new Tuple<int, char>(kvp.Value, kvp.Key));
        }
        v = v.OrderBy(t => t.Item1).ToList();
 
        // If the most occurred character is less than
        // required positions
        if (v.Last().Item1 < sz)
        {
            Console.WriteLine(-1);
            return;
        }
 
        // In all required positions keep
        // the character which occurred most times
        for (int i = 2; i <= n; i++)
        {
            if (sieve[i] == 0)
            {
                ans[i] = v.Last().Item2;
            }
        }
 
        // Fill all other indexes with
        // remaining characters
        int idx = 0;
        for (int i = 1; i <= n; i++)
        {
            if (sieve[i] == 1)
            {
                ans[i] = v[idx].Item2;
                v[idx] = new Tuple<int, char>(v[idx].Item1 - 1, v[idx].Item2);
                // If character frequency becomes
                // zero then go to the next character
                if (v[idx].Item1 == 0)
                    idx++;
            }
            Console.Write(ans[i]);
        }
    }
 
    // Driver code
    static void Main()
    {
        string str = "aabaaaa";
 
        int n = str.Length;
 
        // Function call
        Rearrange(str, n);
    }
}




// Javascript program for the above approach
 
const N = 100005;
const ans = new Array(N).fill(0);
 
function Rearrange(s, n) {
  const sieve = new Array(N + 1).fill(1);
  let sz = 0;
 
  for (let i = 2; i <= Math.floor(n / 2); i++) {
    if (sieve[i]) {
      for (let j = 1; j <= Math.floor(n / i); j++) {
        if (sieve[i * j]) {
          sz += 1;
        }
        sieve[i * j] = 0;
      }
    }
  }
 
  const m = {};
  for (const c of s) {
    m = (m || 0) + 1;
  }
 
  const v = [];
  for (const [key, value] of Object.entries(m)) {
    v.push([value, key]);
  }
 
  v.sort();
 
  if (v[v.length - 1][0] < sz) {
    console.log(-1);
    return;
  }
 
  for (let i = 2; i <= n; i++) {
    if (!sieve[i]) {
      ans[i] = v[v.length - 1][1];
    }
  }
 
  let idx = 0;
  for (let i = 1; i <= n; i++) {
    if (sieve[i]) {
      ans[i] = v[idx][1];
      v[idx][0] -= 1;
      if (v[idx][0] === 0) {
        idx += 1;
      }
    }
    process.stdout.write(ans[i] || '');
  }
}
 
const string = 'aabaaaa';
const n = string.length;
Rearrange(string, n);
 
 
 
// contributed by adityasharmadev01

Output
baaaaaa




Article Tags :