给定字符串S ,任务是找到将给定字符串划分/划分为子字符串S1,S2,S3,…,Sk的方式的数目,以使S1
例子:
Input: S = “aabc”
Output: 6
Following are the allowed partitions:
{“aabc”}, {“aa”, “bc”}, {“aab”, “c”}, {“a”, “abc”},
{“a, “ab”, “c”} and {“aa”, “b”, “c”}.
Input: S = “za”
Output: 1
Only possible partition is {“za”}.
方法:可以使用动态编程解决此问题。
- 将DP [i] [j]定义为分割子字符串S [0…j]的方式数,以使S [i,j]是最后一个分区。
- 现在,对于所有k≥0且i≤N – 1的递归关系将为DP [i] [j] =(DP [k] [i – 1])的总和,其中N是字符串的长度。
- 最终答案将是0到N – 1之间所有i的(DP [i] [N – 1])之和,因为这些子字符串将以某种可能的分区方式成为最后的分区。
- 因此,在这里,对于所有子字符串S [i] [j] ,找到子字符串S [k] [i – 1] ,以使S [k] [i – 1]在字典上小于S [i] [j]并将DP [k] [i – 1]添加到DP [i] [j] 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the number of
// ways of partioning
int ways(string s, int n)
{
int dp[n][n];
// Initialize DP table
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
dp[i][j] = 0;
}
// Base Case
for (int i = 0; i < n; i++)
dp[0][i] = 1;
for (int i = 1; i < n; i++) {
// To store sub-string S[i][j]
string temp;
for (int j = i; j < n; j++) {
temp += s[j];
// To store sub-string S[k][i-1]
string test;
for (int k = i - 1; k >= 0; k--) {
test += s[k];
if (test < temp) {
dp[i][j] += dp[k][i - 1];
}
}
}
}
int ans = 0;
for (int i = 0; i < n; i++) {
// Add all the ways where S[i][n-1]
// will be the last partition
ans += dp[i][n - 1];
}
return ans;
}
// Driver code
int main()
{
string s = "aabc";
int n = s.length();
cout << ways(s, n);
return 0;
}
Java
// Java implementation of the above approach
class GFG
{
// Function to return the number of
// ways of partioning
static int ways(String s, int n)
{
int dp[][] = new int[n][n];
// Initialize DP table
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
dp[i][j] = 0;
}
// Base Case
for (int i = 0; i < n; i++)
dp[0][i] = 1;
for (int i = 1; i < n; i++)
{
// To store sub-string S[i][j]
String temp = "";
for (int j = i; j < n; j++)
{
temp += s.charAt(j);
// To store sub-string S[k][i-1]
String test = "";
for (int k = i - 1; k >= 0; k--)
{
test += s.charAt(k);
if (test.compareTo(temp) < 0)
{
dp[i][j] += dp[k][i - 1];
}
}
}
}
int ans = 0;
for (int i = 0; i < n; i++)
{
// Add all the ways where S[i][n-1]
// will be the last partition
ans += dp[i][n - 1];
}
return ans;
}
// Driver code
public static void main (String[] args)
{
String s = "aabc";
int n = s.length();
System.out.println(ways(s, n));
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 implementation of the approach
# Function to return the number of
# ways of partioning
def ways(s, n):
dp = [[0 for i in range(n)]
for i in range(n)]
# Base Case
for i in range(n):
dp[0][i] = 1
for i in range(1, n):
# To store sub-S[i][j]
temp = ""
for j in range(i, n):
temp += s[j]
# To store sub-S[k][i-1]
test = ""
for k in range(i - 1, -1, -1):
test += s[k]
if (test < temp):
dp[i][j] += dp[k][i - 1]
ans = 0
for i in range(n):
# Add all the ways where S[i][n-1]
# will be the last partition
ans += dp[i][n - 1]
return ans
# Driver code
s = "aabc"
n = len(s)
print(ways(s, n))
# This code is contributed by Mohit Kumarv
C#
// C# implementation of the above approach
using System;
class GFG
{
// Function to return the number of
// ways of partioning
static int ways(String s, int n)
{
int [,]dp = new int[n, n];
// Initialize DP table
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
dp[i, j] = 0;
}
// Base Case
for (int i = 0; i < n; i++)
dp[0, i] = 1;
for (int i = 1; i < n; i++)
{
// To store sub-string S[i,j]
String temp = "";
for (int j = i; j < n; j++)
{
temp += s[j];
// To store sub-string S[k,i-1]
String test = "";
for (int k = i - 1; k >= 0; k--)
{
test += s[k];
if (test.CompareTo(temp) < 0)
{
dp[i, j] += dp[k, i - 1];
}
}
}
}
int ans = 0;
for (int i = 0; i < n; i++)
{
// Add all the ways where S[i,n-1]
// will be the last partition
ans += dp[i, n - 1];
}
return ans;
}
// Driver code
public static void Main (String[] args)
{
String s = "aabc";
int n = s.Length;
Console.WriteLine(ways(s, n));
}
}
// This code is contributed by PrinciRaj1992
输出:
6