给定两个正整数N和K,该任务是找到能够从第一N字母,使得该字符串中的字符字典顺序排序来生成的K个长度的字符串的数目。
例子:
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
天真的方法:解决问题的最简单方法是使用递归和回溯来生成字符的所有可能排列,并针对每个字符串,检查字符遵循词典编排的升序。打印所有这些字符串的计数。
时间复杂度: O(K N )
辅助空间: O(1)
高效方法:为了优化上述方法,我们的想法是使用动态编程,因为有重叠的子问题可以通过使用辅助2D数组dp [] []在递归调用中加以记忆或制表,并计算每个状态的值自下而上的方法。
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
请按照以下步骤解决此问题:
- 初始化大小为(N + 1)的数组columnSum [] ,其中columnSum [i]是数组dp [] []的列“ j”中所有值的总和。
- 初始化大小为(K +1)*(N +1)的dp [] []表。
- 将dp [0] [i]初始化为1 ,然后更新数组columnSum [] 。
- 在K上分别使用变量i和j迭代两个嵌套循环:
- 将dp [i] [j]存储为columnSum [j – 1] 。
- 将columnSum [j]更新为columnSum [j] + dp [i] [j] 。
- 完成上述步骤后,将dp [K] [N]的值打印为合成的路数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count K-length
// strings from first N alphabets
void waysToArrangeKLengthStrings(
int N, int K)
{
// To keep track of column sum in dp
int column_sum[N + 1] = { 0 }, i, j;
// Auxiliary 2d dp array
int dp[K + 1][N + 1] = { 0 };
// Initialize dp[0][i] = 1 and
// update the column_sum
for (i = 0; i <= N; i++) {
dp[0][i] = 1;
column_sum[i] = 1;
}
// Iterate for K times
for (i = 1; i <= K; i++) {
// Iterate for N times
for (j = 1; j <= N; j++) {
// dp[i][j]: Stores the number
// of ways to form i-length
// strings consisting of j letters
dp[i][j] += column_sum[j - 1];
// Update the column_sum
column_sum[j] += dp[i][j];
}
}
// Print number of ways to arrange
// K-length strings with N alphabets
cout << dp[K][N];
}
// Driver Code
int main()
{
// Given N and K
int N = 5, K = 2;
// Function Call
waysToArrangeKLengthStrings(N, K);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG{
// Function to count K-length
// strings from first N alphabets
static void waysToArrangeKLengthStrings(
int N, int K)
{
// To keep track of column sum in dp
int[] column_sum = new int[N + 1];
int i, j;
for(i = 1; i < N + 1; i++)
{
column_sum[i] = 0;
}
// Auxiliary 2d dp array
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;
}
}
// Initialize dp[0][i] = 1 and
// update the column_sum
for(i = 0; i <= N; i++)
{
dp[0][i] = 1;
column_sum[i] = 1;
}
// Iterate for K times
for(i = 1; i <= K; i++)
{
// Iterate for N times
for(j = 1; j <= N; j++)
{
// dp[i][j]: Stores the number
// of ways to form i-length
// strings consisting of j letters
dp[i][j] += column_sum[j - 1];
// Update the column_sum
column_sum[j] += dp[i][j];
}
}
// Print number of ways to arrange
// K-length strings with N alphabets
System.out.print(dp[K][N]);
}
// Driver Code
public static void main(String[] args)
{
// Given N and K
int N = 5, K = 2;
// Function Call
waysToArrangeKLengthStrings(N, K);
}
}
// This code is contributed by susmitakundugoaldanga
Python3
# Python3 program for the above approach
# Function to count K-length
# strings from first N alphabets
def waysToArrangeKLengthStrings(N, K):
# To keep track of column sum in dp
column_sum = [0 for i in range(N + 1)]
i = 0
j = 0
# Auxiliary 2d dp array
dp = [[0 for i in range(N + 1)]
for j in range(K + 1)]
# Initialize dp[0][i] = 1 and
# update the column_sum
for i in range(N + 1):
dp[0][i] = 1
column_sum[i] = 1
# Iterate for K times
for i in range(1, K + 1):
# Iterate for N times
for j in range(1, N + 1):
# dp[i][j]: Stores the number
# of ways to form i-length
# strings consisting of j letters
dp[i][j] += column_sum[j - 1]
# Update the column_sum
column_sum[j] += dp[i][j]
# Print number of ways to arrange
# K-length strings with N alphabets
print(dp[K][N])
# Driver Code
if __name__ == '__main__':
# Given N and K
N = 5
K = 2
# Function Call
waysToArrangeKLengthStrings(N, K)
# This code is contributed by SURENDRA_GANGWAR
C#
// C# program for the above approach
using System;
class GFG{
// Function to count K-length
// strings from first N alphabets
static void waysToArrangeKLengthStrings(int N,
int K)
{
// To keep track of column sum in dp
int[] column_sum = new int[N + 1];
int i, j;
for(i = 1; i < N + 1; i++)
{
column_sum[i] = 0;
}
// Auxiliary 2d dp array
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;
}
}
// Initialize dp[0][i] = 1 and
// update the column_sum
for(i = 0; i <= N; i++)
{
dp[0, i] = 1;
column_sum[i] = 1;
}
// Iterate for K times
for(i = 1; i <= K; i++)
{
// Iterate for N times
for(j = 1; j <= N; j++)
{
// dp[i][j]: Stores the number
// of ways to form i-length
// strings consisting of j letters
dp[i, j] += column_sum[j - 1];
// Update the column_sum
column_sum[j] += dp[i, j];
}
}
// Print number of ways to arrange
// K-length strings with N alphabets
Console.Write(dp[K, N]);
}
// Driver Code
public static void Main()
{
// Given N and K
int N = 5, K = 2;
// Function Call
waysToArrangeKLengthStrings(N, K);
}
}
// This code is contributed by code_hunt
Javascript
15
时间复杂度: O(N * K)
辅助空间: O(N * K)