Thursday, October 23, 2025
HomeData Modelling & AILexicographically smallest permutation of a string with given subsequences

Lexicographically smallest permutation of a string with given subsequences

Given a string consisting only of two lowercase characters x       and y       and two numbers p       and q       . The task is to print the lexicographically smallest permutation of the given string such that the count of subsequences of xy       is p       and of yx       is q       . 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++




// 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 exits
int 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 string
string 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 code
int main()
{
    string s = "yxxyx";
    int p = 3, q = 3;
 
    cout<< smallestPermutation(s, p, q);
     
    return 0;
}


Java




// 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 Code
public 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




# 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 exits
def 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 string
def 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 code
if __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#




// 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 Code
public 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


Javascript




<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 Code
let s = "yxxyx";
let p = 3;
let q = 3;
 
document.write(smallestPermutation(s, p, q));
 
// This code is contributed by patel2127
</script>


Output

xyxyx

Time Complexity: O(N2)
Auxiliary Space: O(1)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Dominic
32361 POSTS0 COMMENTS
Milvus
88 POSTS0 COMMENTS
Nango Kala
6728 POSTS0 COMMENTS
Nicole Veronica
11892 POSTS0 COMMENTS
Nokonwaba Nkukhwana
11954 POSTS0 COMMENTS
Shaida Kate Naidoo
6852 POSTS0 COMMENTS
Ted Musemwa
7113 POSTS0 COMMENTS
Thapelo Manthata
6805 POSTS0 COMMENTS
Umr Jansen
6801 POSTS0 COMMENTS