- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Lexicographically Kth-smallest string having ‘a’ X times and ‘b’ Y times
Lexicographically Kth-smallest string having ‘a’ X times and ‘b’ Y times is a problem where we need to find the Kth smallest string that contains X number of ‘a’s and Y number of ‘b’s. The strings are arranged lexicographically which means that the smallest string comes first when we sort all the possible strings.
In this tutorial, we will discuss how to solve this problem using C++. We will start by understanding the problem statement in detail, followed by the algorithmic approach. We will then move on to implementing the solution in C++ using dynamic programming. The code will be explained in detail, along with the step-by-step approach to solving the problem. By the end of this tutorial, you will have a clear understanding of how to solve this problem and the implementation details in C++. So let’s get started!
Problem Statement
The objective is to identify the Kth smallest string in lexicographical order that consists of X instances of character 'a' and Y instances of character 'b'. The input for this problem is three non-negative integers X, Y, and K.
Sample Example 1
Input
X=2, Y=3, K=3
Output
abbab
Explanation: The lexicographically first three smallest strings with 2 'a's and 3 'b's are "aabbb", "ababb", and "abbab". Hence, the third lexicographically smallest string is "abbab".
Sample Example 2
Input
X=4, Y=3, K=4
Output
aaabbba
Explanation: The lexicographically fourth smallest string with 4 'a's and 3 'b's is "aaabbba".
Algorithm
STEP 1. Create a function ‘fillDpArray’ that takes parameters ‘X’, ‘Y’, ‘dp[][MAX]’, ‘rows’, and ‘cols’:
Use ‘memset’ to fill the entire ‘dp’ array with 0s.
Set ‘dp[0][0]’ to 1.
Use nested loops to traverse the ‘dp’ array:
For each element ‘dp[i][j]’, update its value by adding the values of ‘dp[i - 1][j]’ and ‘dp[i][j - 1]’.
STEP 2. Create a recursive function ‘findKthString’ that takes parameters ‘X’, ‘Y’, ‘K’, and ‘dp[][MAX]’:
Handle the base cases:
If ‘X’ is 0, return a string of 'b' characters with length ‘Y’.
If ‘Y’ is 0, return a string of 'a' characters with length ‘X’.
Check if ‘K’ is less than or equal to ‘dp[X - 1][Y]’:
If true, return the concatenation of the character 'a' and the result of calling ‘findKthString’ with arguments ‘X - 1’, ‘Y’, ‘K’, and ‘dp’.
Otherwise:
Return the concatenation of the character 'b' and the result of calling findKthString with arguments ‘X’, ‘Y - 1’, ‘K - dp[X - 1][Y]’, and ‘dp’.
STEP 3. In the ‘main’ function:
Declare variables ‘X’, ‘Y’, and ‘K’ to store user input.
Read input values for ‘X’, ‘Y’, and ‘K’ from the user.
Validate the input values to ensure they meet the required criteria ‘(X >= 0, Y >= 0, and K > 0)’.
Create a 2D array ‘dp[MAX][MAX]’.
If the input values are valid, call the ‘fillDpArray’ function with arguments ‘X’, ‘Y’, ‘dp’, ‘MAX’, and ‘MAX’ to calculate the ‘dp’ array.
Check if the input values are valid and ‘K’ is less than or equal to ‘dp[X][Y]’:
If true, call the findKthString function with arguments ‘X’, ‘Y’, ‘K’, and ‘dp’ to get the Kth lexicographically smallest string.
Display the outcome by printing the string obtained from ‘findKthString’.
Otherwise, display an error message indicating invalid input values.
Now, let’s see the implementation of the above algorithm using C++ with the help of an example.
Example
Implementation of the above algorithm using C++
The below C++ program calculates the lexicographically Kth smallest string consisting of 'a's and 'b's. It uses dynamic programming to fill a 2D array, ‘dp’, with the count of valid strings for each combination of 'a's and 'b's. The ‘fillDpArray’ function initializes the array and updates its values based on previous values. The ‘findKthString’ function recursively constructs the Kth string by checking the count of strings starting with 'a' in ‘dp’ and recursively calling itself with updated values. The main function reads input values, validates them, calculates the result using ‘fillDpArray’ if the input is valid, and displays the outcome or an error message.
#include <iostream> #include <cstring> const int MAX = 30; // Function to fill a 2D dp array with 0s void fillDpArray(int X, int Y, int dp[][MAX], int rows, int cols) { memset(dp, 0, rows * cols * sizeof(int)); dp[0][0] = 1; // Traverse the dp array and update its values for (int i = 0; i <= X; ++i) { for (int j = 0; j <= Y; ++j) { // Update the value of dp[i][j] based on previous values if (i > 0) { dp[i][j] += dp[i - 1][j]; } if (j > 0) { dp[i][j] += dp[i][j - 1]; } } } } // Recursive function to find the Kth lexicographically smallest string std::string findKthString(int X, int Y, int K, int dp[][MAX]) { // Handle base cases where the string has only one character if (X == 0) { return std::string(Y, 'b'); } if (Y == 0) { return std::string(X, 'a'); } // If there are more than or equal to K strings which start with 'a', //Then the first character is 'a' if (K <= dp[X - 1][Y]) { return std::string("a") + findKthString(X - 1, Y, K, dp); } // Otherwise, the first character of the resultant string is 'b' else { return std::string("b") + findKthString(X, Y - 1, K - dp[X - 1][Y], dp); } } int main() { // Input variables int X=4, Y=3, K=4; // Validate the input values to ensure they meet the required criteria bool isValid = X >= 0 && Y >= 0 && K > 0; // Calculate the result int dp[MAX][MAX]; if (isValid) { fillDpArray(X, Y, dp, MAX, MAX); } // Display the outcome or an error message if (isValid && K <= dp[X][Y]) { std::string kthString = findKthString(X, Y, K, dp); std::cout << "The " << K << "th lexicographically smallest string with " << X << " 'a's and " << Y << " 'b's is: " << kthString << std::endl; } else { std::cout << "Invalid input values. Please enter non-negative integers for 'a's and 'b's, and a positive integer for K." << std::endl; } return 0; }
Output
The 4th lexicographically smallest string with 4 'a's and 3 'b's is: aaabbba
Conclusion
To sum up, finding the Kth lexicographically smallest string with given numbers of 'a's and 'b's requires the use of dynamic programming. By filling a 2D DP array and using a recursive function, we can find the Kth lexicographically smallest string. The time complexity of this algorithm is O(X * Y), where X and Y are the numbers of 'a's and 'b's respectively. This algorithm can be applied to a variety of problems that require finding the Kth lexicographically smallest string.