Lexicographically smallest permutation of a string with given subsequences

09 Dec, 2021
Given a string consisting only of two lowercase characters and and two numbers and . The task is to print the lexicographically smallest permutation of the given string such that the count of subsequences of is and of is . If no such string exists, print “Impossible” (without quotes).Examples:  
Input: str = "yxxyx", p = 3, q = 3 
Output: xyxyx

Input: str = "yxxy", p = 3, q = 2
Output: Impossible
 
Approach: First of all, by induction it can prove that the product of count of ‘x’ and count of ‘y’ should be equal to the sum of the count of a subsequence of ‘xy’ and ‘yx’ for any given string. If this does not hold then the answer is ‘Impossible’ else answer always exist.Now, sort the given string so the count of a subsequence of ‘yx’ becomes zero. Let nx be the count of ‘x’ and ny be count of ‘y’. let a and b be the count of subsequence ‘xy’ and ‘yx’ respectively, then a = nx*ny and b = 0. Then, from beginning of the string find the ‘x’ which has next ‘y’ to it and swap both until you reach end of the string. In each swap a is decremented by 1 and b is incremented by 1. Repeat this until the count of a subsequence of ‘yx’ is achieved i:e a becomes p and b becomes q.Below is the implementation of the above approach:  
C++
Java
Python3
C#
Javascript
// CPP program to find lexicographically smallest// string such that count of subsequence 'xy' and// 'yx' is p and q respectively.#include <bits/stdc++.h>using namespace std; // function to check if answer exitsint nx = 0, ny = 0; bool check(string s, int p, int q){    // count total 'x' and 'y' in string    for (int i = 0; i < s.length(); ++i) {        if (s[i] == 'x')            nx++;        else            ny++;    }     // condition to check existence of answer    if (nx * ny != p + q)        return 1;    else        return 0;} // function to find lexicographically smallest stringstring smallestPermutation(string s, int p, int q){    // check if answer exist or not    if (check(s, p, q) == 1) {        return "Impossible";    }     sort(s.begin(), s.end());    int a = nx * ny, b = 0, i, j;     // check if count of 'xy' and 'yx' becomes    // equal to p and q respectively.    if (a == p && b == q) {        return s;    }     // Repeat until answer is found.    while (1) {        // Find index of 'x' to swap with 'y'.        for (i = 0; i < s.length() - 1; ++i) {            if (s[i] == 'x' && s[i + 1] == 'y')                break;        }         for (j = i; j < s.length() - 1; j++) {            if (s[j] == 'x' && s[j + 1] == 'y') {                swap(s[j], s[j + 1]);                a--; // 'xy' decrement by 1                b++; // 'yx' increment by 1                 // check if count of 'xy' and 'yx' becomes                // equal to p and q respectively.                if (a == p && b == q) {                    return s;                }            }        }    }} // Driver codeint main(){    string s = "yxxyx";    int p = 3, q = 3;     cout<< smallestPermutation(s, p, q);         return 0;}
// Java program to find lexicographically// smallest string such that count of// subsequence 'xy' and 'yx' is p and// q respectively.import java.util.*; class GFG{static int nx = 0, ny = 0;     static boolean check(String s,                     int p, int q){    // count total 'x' and 'y' in string    for (int i = 0; i < s.length(); ++i)    {        if (s.charAt(i) == 'x')            nx++;        else            ny++;    }     // condition to check    // existence of answer    if ((nx * ny) != (p + q))        return true;    else        return false;} public static String smallestPermutation(String s,                                         int p, int q){    if (check(s, p, q) == true)    {        return "Impossible";    }             char tempArray[] = s.toCharArray();    Arrays.sort(tempArray);         String str = new String(tempArray);    int a = nx * ny, b = 0, i = 0, j = 0;             if (a == p && b == q)    {        return str;    }         while (1 > 0)    {             // Find index of 'x' to swap with 'y'.    for (i = 0; i < str.length() - 1; ++i)    {        if (str.charAt(i) == 'x' &&            str.charAt(i + 1) == 'y')            break;    }     for (j = i; j < str.length() - 1; j++)    {        if (str.charAt(j) == 'x' &&            str.charAt(j + 1) == 'y')        {        StringBuilder sb = new StringBuilder(str);        sb.setCharAt(j, str.charAt(j + 1));        sb.setCharAt(j + 1, str.charAt(j));        str = sb.toString();        /* char ch[] = str.toCharArray();            char temp = ch[j+1];            ch[j+1] = ch[j];            ch[j] = temp;*/                         a--; // 'xy' decrement by 1            b++; // 'yx' increment by 1             // check if count of 'xy' and            // 'yx' becomes equal to p            // and q respectively.            if (a == p && b == q)            {                return str;            }        }    }}} // Driver Codepublic static void main (String[] args){    String s = "yxxyx";    int p = 3, q = 3;         System.out.print(smallestPermutation(s, p, q));}} // This code is contributed by Kirti_Mangal
# Python3 program to find lexicographically# smallest string such that count of subsequence# 'xy' and 'yx' is p and q respectively. # Function to check if answer exitsdef check(s, p, q):         global nx    global ny         # count total 'x' and 'y' in string    for i in range(0, len(s)):        if s[i] == 'x':            nx += 1        else:            ny += 1     # condition to check existence of answer    if nx * ny != p + q:        return 1    else:        return 0 # Function to find lexicographically# smallest stringdef smallestPermutation(s, p, q):     # check if answer exist or not    if check(s, p, q) == 1:        return "Impossible"     s = sorted(s)    a, b, i = nx * ny, 0, 0     # check if count of 'xy' and 'yx' becomes    # equal to p and q respectively.    if a == p and b == q:        return '' . join(s)     # Repeat until answer is found.    while True:                 # Find index of 'x' to swap with 'y'.        for i in range(0, len(s) - 1):            if s[i] == 'x' and s[i + 1] == 'y':                break         for j in range(i, len(s) - 1):            if s[j] == 'x' and s[j + 1] == 'y':                                 s[j], s[j + 1] = s[j + 1], s[j]                a -= 1 # 'xy' decrement by 1                b += 1 # 'yx' increment by 1                 # check if count of 'xy' and 'yx' becomes                # equal to p and q respectively.                if a == p and b == q:                    return '' . join(s) # Driver codeif __name__ == "__main__":         nx, ny = 0, 0    s = "yxxyx"    p, q = 3, 3     print(smallestPermutation(s, p, q))     # This code is contributed by Rituraj Jain
// C# program to find lexicographically// smallest string such that count of// subsequence 'xy' and 'yx' is p and// q respectively.using System;using System.Text; class GFG{     static int nx = 0, ny = 0;     static Boolean check(String s,                    int p, int q){    // count total 'x' and 'y' in string    for (int i = 0; i < s.Length; ++i)    {        if (s[i] == 'x')            nx++;        else            ny++;    }     // condition to check    // existence of answer    if ((nx * ny) != (p + q))        return true;    else        return false;} public static String smallestPermutation(String s,                                        int p, int q){    if (check(s, p, q) == true)    {        return "Impossible";    }             char []tempArray = s.ToCharArray();    Array.Sort(tempArray);         String str = new String(tempArray);    int a = nx * ny, b = 0, i = 0, j = 0;             if (a == p && b == q)    {        return str;    }         while (1 > 0)    {             // Find index of 'x' to swap with 'y'.    for (i = 0; i < str.Length - 1; ++i)    {        if (str[i] == 'x' &&            str[i + 1] == 'y')            break;    }     for (j = i; j < str.Length - 1; j++)    {        if (str[j] == 'x' &&            str[j + 1] == 'y')        {            StringBuilder sb = new StringBuilder(str);            sb.Remove(j,1);            sb.Insert(j, str[j + 1]);            sb.Remove(j+1,1);            sb.Insert(j + 1, str[j]);            str = sb.ToString();            /* char ch[] = str.toCharArray();                char temp = ch[j+1];                ch[j+1] = ch[j];                ch[j] = temp;*/                         a--; // 'xy' decrement by 1            b++; // 'yx' increment by 1             // check if count of 'xy' and            // 'yx' becomes equal to p            // and q respectively.            if (a == p && b == q)            {                return str;            }        }    }}} // Driver Codepublic static void Main (String[] args){    String s = "yxxyx";    int p = 3, q = 3;         Console.WriteLine(smallestPermutation(s, p, q));}} // This code has been contributed by 29AjayKumar
<script>// Javascript program to find lexicographically// smallest string such that count of// subsequence 'xy' and 'yx' is p and// q respectively. let nx = 0, ny = 0;function check(s, p, q){    // count total 'x' and 'y' in string    for (let i = 0; i < s.length; ++i)    {        if (s[i] == 'x')            nx++;        else            ny++;    }       // condition to check    // existence of answer    if ((nx * ny) != (p + q))        return true;    else        return false;} function smallestPermutation(s,p,q){    if (check(s, p, q) == true)    {        return "Impossible";    }               let tempArray = s.split("");    (tempArray).sort();           let str = (tempArray).join("");    let a = nx * ny, b = 0, i = 0, j = 0;               if (a == p && b == q)    {        return str;    }           while (1 > 0)    {               // Find index of 'x' to swap with 'y'.    for (i = 0; i < str.length - 1; ++i)    {        if (str[i] == 'x' &&            str[i+1] == 'y')            break;    }       for (j = i; j < str.length - 1; j++)    {        if (str[j] == 'x' &&            str[j+1] == 'y')        {        let sb = (str).split("");        sb[j] = str[j+1];        sb[j + 1] = str[j];        str = sb.join("");        /* char ch[] = str.toCharArray();            char temp = ch[j+1];            ch[j+1] = ch[j];            ch[j] = temp;*/                           a--; // 'xy' decrement by 1            b++; // 'yx' increment by 1               // check if count of 'xy' and            // 'yx' becomes equal to p            // and q respectively.            if (a == p && b == q)            {                return str;            }        }    }}} // Driver Codelet s = "yxxyx";let p = 3;let q = 3; document.write(smallestPermutation(s, p, q)); // This code is contributed by patel2127</script>
xyxyx
 
Time Complexity: O(N2) 
Kirti_Mangal
rituraj_jain
29AjayKumar
patel2127
clintra
Algorithms
Greedy
Strings
Strings
Greedy
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
What is Hashing | A Complete Tutorial
Find if there is a path between two vertices in an undirected graph
How to Start Learning DSA?
Complete Roadmap To Learn DSA From Scratch
Types of Complexity Classes | P, NP, CoNP, NP hard and NP complete
Dijkstra's shortest path algorithm | Greedy Algo-7
Program for array rotation
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Write a program to print all permutations of a given string
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2