Count lexicographically increasing K-length strings possible from first N alphabets
Last Updated :
28 Oct, 2023
Given two positive integers N and K, the task is to find the number of K length strings that can be generated from the first N alphabets such that the characters in the string are sorted lexicographically.
Examples:
Input: N = 5, K = 2
Output: 15
Explanation: All possible strings are {“AA”, “AB”, “AC”, “AD”, “AE”, “BB”, “BC”, “BD”, “BE”, “CC”, “CD”, “CE”, “DD”, “DE”, “EE”}.
Input: N = 7, K = 10
Output: 8008
Naive Approach: The simplest approach to solve the problem is to use Recursion and Backtracking to generate all possible arrangements of characters and for each string, check if the characters follow a lexicographically increasing order or not. Print the count of all such strings.
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<string> generateStrings(string curr_str, int curr_char, int N, int K) {
if (curr_str.length() == K) {
vector<string> res;
res.push_back(curr_str);
return res;
}
vector<string> res;
for ( int i = curr_char; i < N; i++) {
vector<string> suffixes = generateStrings(curr_str + char (65 + i), i, N, K);
res.insert(res.end(), suffixes.begin(), suffixes.end());
}
return res;
}
int countStrings( int N, int K) {
vector<string> all_strings = generateStrings( "" , 0, N, K);
vector<string> sorted_strings;
for ( int i = 0; i < all_strings.size(); i++) {
string s = all_strings[i];
if (is_sorted(s.begin(), s.end())) {
sorted_strings.push_back(s);
}
}
return sorted_strings.size();
}
int main() {
cout << countStrings(5, 2) << endl;
cout << countStrings(7, 10) << endl;
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.List;
public class Main {
static List<String> generateStrings(String currStr, int currChar, int N, int K) {
if (currStr.length() == K) {
List<String> res = new ArrayList<>();
res.add(currStr);
return res;
}
List<String> res = new ArrayList<>();
for ( int i = currChar; i < N; i++) {
List<String> suffixes = generateStrings(currStr + ( char ) ( 'A' + i), i, N, K);
res.addAll(suffixes);
}
return res;
}
static int countStrings( int N, int K) {
List<String> allStrings = generateStrings( "" , 0 , N, K);
List<String> sortedStrings = new ArrayList<>();
for (String s : allStrings) {
if (isSorted(s)) {
sortedStrings.add(s);
}
}
return sortedStrings.size();
}
static boolean isSorted(String s) {
for ( int i = 1 ; i < s.length(); i++) {
if (s.charAt(i - 1 ) > s.charAt(i)) {
return false ;
}
}
return true ;
}
public static void main(String[] args) {
System.out.println(countStrings( 5 , 2 ));
System.out.println(countStrings( 7 , 10 ));
}
}
|
Python
def count_strings(N, K):
def generate_strings(curr_str, curr_char, K):
if len (curr_str) = = K:
return [curr_str]
res = []
for i in range (curr_char, N):
res.extend(generate_strings(curr_str + chr ( 65 + i), i, K))
return res
all_strings = generate_strings("", 0 , K)
sorted_strings = [s for s in all_strings if list (s) = = sorted ( list (s))]
return len (sorted_strings)
print (count_strings( 5 , 2 ))
print (count_strings( 7 , 10 ))
|
C#
using System;
using System.Collections.Generic;
public class SortedStringsCount
{
static List< string > GenerateStrings( string currStr, int currChar, int N, int K)
{
if (currStr.Length == K)
{
List< string > result = new List< string >();
result.Add(currStr);
return result;
}
List< string > resultStrings = new List< string >();
for ( int i = currChar; i < N; i++)
{
List< string > suffixes = GenerateStrings(currStr + ( char )( 'A' + i), i, N, K);
resultStrings.AddRange(suffixes);
}
return resultStrings;
}
static int CountSortedStrings( int N, int K)
{
List< string > allStrings = GenerateStrings( "" , 0, N, K);
List< string > sortedStrings = new List< string >();
foreach ( string s in allStrings)
{
if (IsSorted(s))
{
sortedStrings.Add(s);
}
}
return sortedStrings.Count;
}
static bool IsSorted( string s)
{
for ( int i = 1; i < s.Length; i++)
{
if (s[i] < s[i - 1])
{
return false ;
}
}
return true ;
}
public static void Main( string [] args)
{
Console.WriteLine(CountSortedStrings(5, 2));
Console.WriteLine(CountSortedStrings(7, 10));
}
}
|
Javascript
function countStrings(N, K) {
function generateStrings(currStr, currChar, K) {
if (currStr.length === K) {
return [currStr];
}
let res = [];
for (let i = currChar; i < N; i++) {
res.push(...generateStrings(currStr + String.fromCharCode(65 + i), i, K));
}
return res;
}
let allStrings = generateStrings( "" , 0, K);
let sortedStrings = allStrings.filter(s => [...s].sort().join( "" ) === s);
return sortedStrings.length;
}
console.log(countStrings(5, 2));
console.log(countStrings(7, 10));
|
Time Complexity: O(KN)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to use Dynamic Programming as there are overlapping subproblems that can be memoized or tabulated in the recursive calls by using an auxiliary 2D array dp[][] and calculate the value of each state in the bottom-up approach.
dp[i][j] represents the number of ways to arrange “i” length strings with the “j” distinct letters.
dp[i][j] = dp[i][j – 1] (Choose not to start with first letter)
+ dp[i – 1][j – 1] (Choose first 1 letter in string as first letter)
+ dp[i – 2][j – 1] (Choose first 2 letters in string as first letter)
+ ….
+ ….
+ dp[0][j – 1] (Choose first i letters in string as first letter)
dp[i][j] = Sum of all values of (j-1)th column for “i” rows
Follow the steps below to solve this problem:
- Initialize an array columnSum[] of size (N+1), where columnSum[i] is sum of all values in column “j” of the array dp[][].
- Initialize a dp[][] table of size (K + 1)*(N + 1).
- Initialize dp[0][i] as 1 and subsequently update array columnSum[].
- Iterate two nested loops over K and using the variable i and j respectively:
- Store dp[i][j] as columnSum[j – 1].
- Update columnSum[j] as columnSum[j] + dp[i][j].
- After the above steps, print the value of dp[K][N] as the resultant number of ways.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void waysToArrangeKLengthStrings(
int N, int K)
{
int column_sum[N + 1] = { 0 }, i, j;
int dp[K + 1][N + 1] = { 0 };
for (i = 0; i <= N; i++) {
dp[0][i] = 1;
column_sum[i] = 1;
}
for (i = 1; i <= K; i++) {
for (j = 1; j <= N; j++) {
dp[i][j] += column_sum[j - 1];
column_sum[j] += dp[i][j];
}
}
cout << dp[K][N];
}
int main()
{
int N = 5, K = 2;
waysToArrangeKLengthStrings(N, K);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG{
static void waysToArrangeKLengthStrings(
int N, int K)
{
int [] column_sum = new int [N + 1 ];
int i, j;
for (i = 1 ; i < N + 1 ; i++)
{
column_sum[i] = 0 ;
}
int dp[][] = new int [K + 1 ][N + 1 ];
for (i = 1 ; i < K + 1 ; i++)
{
for (j = 1 ; j < N + 1 ; j++)
{
dp[i][j] = 0 ;
}
}
for (i = 0 ; i <= N; i++)
{
dp[ 0 ][i] = 1 ;
column_sum[i] = 1 ;
}
for (i = 1 ; i <= K; i++)
{
for (j = 1 ; j <= N; j++)
{
dp[i][j] += column_sum[j - 1 ];
column_sum[j] += dp[i][j];
}
}
System.out.print(dp[K][N]);
}
public static void main(String[] args)
{
int N = 5 , K = 2 ;
waysToArrangeKLengthStrings(N, K);
}
}
|
Python3
def waysToArrangeKLengthStrings(N, K):
column_sum = [ 0 for i in range (N + 1 )]
i = 0
j = 0
dp = [[ 0 for i in range (N + 1 )]
for j in range (K + 1 )]
for i in range (N + 1 ):
dp[ 0 ][i] = 1
column_sum[i] = 1
for i in range ( 1 , K + 1 ):
for j in range ( 1 , N + 1 ):
dp[i][j] + = column_sum[j - 1 ]
column_sum[j] + = dp[i][j]
print (dp[K][N])
if __name__ = = '__main__' :
N = 5
K = 2
waysToArrangeKLengthStrings(N, K)
|
C#
using System;
class GFG{
static void waysToArrangeKLengthStrings( int N,
int K)
{
int [] column_sum = new int [N + 1];
int i, j;
for (i = 1; i < N + 1; i++)
{
column_sum[i] = 0;
}
int [,] dp = new int [K + 1, N + 1];
for (i = 1; i < K + 1; i++)
{
for (j = 1; j < N + 1; j++)
{
dp[i, j] = 0;
}
}
for (i = 0; i <= N; i++)
{
dp[0, i] = 1;
column_sum[i] = 1;
}
for (i = 1; i <= K; i++)
{
for (j = 1; j <= N; j++)
{
dp[i, j] += column_sum[j - 1];
column_sum[j] += dp[i, j];
}
}
Console.Write(dp[K, N]);
}
public static void Main()
{
int N = 5, K = 2;
waysToArrangeKLengthStrings(N, K);
}
}
|
Javascript
<script>
function waysToArrangeKLengthStrings(N, K)
{
let column_sum = [];
let i, j;
for (i = 1; i < N + 1; i++)
{
column_sum[i] = 0;
}
let dp = new Array(K + 1);
for (i = 0; i < dp.length; i++) {
dp[i] = new Array(2);
}
for (i = 1; i < K + 1; i++)
{
for (j = 1; j < N + 1; j++)
{
dp[i][j] = 0;
}
}
for (i = 0; i <= N; i++)
{
dp[0][i] = 1;
column_sum[i] = 1;
}
for (i = 1; i <= K; i++)
{
for (j = 1; j <= N; j++)
{
dp[i][j] += column_sum[j - 1];
column_sum[j] += dp[i][j];
}
}
document.write(dp[K][N]);
}
let N = 5, K = 2;
waysToArrangeKLengthStrings(N, K);
</script>
|
Time Complexity: O(N*K)
Auxiliary Space: O(N*K)
Share your thoughts in the comments
Please Login to comment...