给定一个字符串,计算 a i b j c k形式的子序列的数量,即,它由 i 个 ‘a’ 个字符,后跟 j 个 ‘b’ 个字符,然后是 k 个 ‘c’ 个字符,其中 i >= 1, j >=1 和 k >= 1。
注意:如果为 2 个子序列选择的数组索引集不同,则认为两个子序列不同。
预期时间复杂度:O(n)
例子:
Input : abbc
Output : 3
Subsequences are abc, abc and abbc
Input : abcabc
Output : 7
Subsequences are abc, abc, abbc, aabc
abcc, abc and abc
方法:
我们遍历给定的字符串。对于每次遇到字符,我们执行以下操作:
1)初始化由’a’的不同组合引起的不同子序列的计数。让这个计数成为一个计数。
2)初始化由’b’的不同组合引起的不同子序列的计数。将此计数设为 bCount。
3)初始化’c’的不同组合引起的不同子序列的计数。将此计数设为 cCount。
4)遍历给定字符串的所有字符。对当前字符s[i]执行以下操作
如果当前字符是 ‘a’ ,则有以下可能性:
a) 当前字符开始一个新的子序列。
b) 当前字符是 aCount 子序列的一部分。
c) 当前字符不是 aCount 子序列的一部分。
因此我们做 aCount = (1 + 2 * aCount);
如果当前字符是 ‘b’ ,则有以下可能性:
a) 当前字符以 aCount 个子序列开始 b 的新子序列。
b) 当前字符是 bCount 子序列的一部分。
c) 当前字符不是 bCount 子序列的一部分。
因此我们做 bCount = (aCount + 2 * bCount);
如果当前字符是 ‘c’ ,则有以下可能性:
a) 当前字符以 bCount 个子序列开始 c 的新子序列。
b) 当前字符是 cCount 子序列的一部分。
c) 当前字符不是 cCount 子序列的一部分。
因此我们做 cCount = (bCount + 2 * cCount);
5)最后我们返回cCount;
在示例的帮助下解释方法:
- aCount 是字母“a”的子序列数。
- 考虑这个例子:aa。
- 我们可以看到 aCount 为 3,因为我们可以选择这些可能性: (xa, ax, aa) (x 表示我们没有使用那个字符)。还要注意,这与中间的字符无关,即 aa 和 ccbabbbcac 的 aCount 是相同的,因为两者都恰好有 2 个 a。
- 现在,加上 1 a,我们现在有以下新子序列:每个旧子序列、每个旧子序列 + 新 a 和新字母 a,单独。所以一共有aCount + aCount + 1个子序列。
- 现在,让我们考虑 bCount,即具有一些 a 和一些 b 的子序列的数量。在“aab”中,我们看到 bCount 应该是 3 (axb, xab, aab) 因为它只是我们可以选择前两个 a 的子序列的方法数,然后是 b。所以每次我们添加 ab 时,方式的数量都会增加 aCount。
- 让我们找到’aabb’的bCount。我们已经确定 aab 有 3 个子序列,所以我们当然还有那些。此外,我们可以将新的 b 添加到这些子序列中的任何一个,以获得 3 个。最后,我们必须计算没有使用任何其他 b 的子序列,根据最后一段的逻辑,这只是 aCount。所以,这之后的 bCount 只是旧的 bCount*2 + aCount;
- cCount 类似。
下面是上述想法的实现:
C++
// C++ program to count subsequences of the
// form a^i b^j c^k
#include
using namespace std;
// Returns count of subsequences of the form
// a^i b^j c^k
int countSubsequences(string s)
{
// Initialize counts of different subsequences
// caused by different combination of 'a'
int aCount = 0;
// Initialize counts of different subsequences
// caused by different combination of 'a' and
// different combination of 'b'
int bCount = 0;
// Initialize counts of different subsequences
// caused by different combination of 'a', 'b'
// and 'c'.
int cCount = 0;
// Traverse all characters of given string
for (unsigned int i = 0; i < s.size(); i++) {
/* If current character is 'a', then
there are the following possibilities :
a) Current character begins a new
subsequence.
b) Current character is part of aCount
subsequences.
c) Current character is not part of
aCount subsequences. */
if (s[i] == 'a')
aCount = (1 + 2 * aCount);
/* If current character is 'b', then
there are following possibilities :
a) Current character begins a new
subsequence of b's with aCount
subsequences.
b) Current character is part of bCount
subsequences.
c) Current character is not part of
bCount subsequences. */
else if (s[i] == 'b')
bCount = (aCount + 2 * bCount);
/* If current character is 'c', then
there are following possibilities :
a) Current character begins a new
subsequence of c's with bCount
subsequences.
b) Current character is part of cCount
subsequences.
c) Current character is not part of
cCount subsequences. */
else if (s[i] == 'c')
cCount = (bCount + 2 * cCount);
}
return cCount;
}
// Driver code
int main()
{
string s = "abbc";
cout << countSubsequences(s) << endl;
return 0;
}
Java
// Java program to count subsequences of the
// form a^i b^j c^k
public class No_of_subsequence {
// Returns count of subsequences of the form
// a^i b^j c^k
static int countSubsequences(String s)
{
// Initialize counts of different subsequences
// caused by different combination of 'a'
int aCount = 0;
// Initialize counts of different subsequences
// caused by different combination of 'a' and
// different combination of 'b'
int bCount = 0;
// Initialize counts of different subsequences
// caused by different combination of 'a', 'b'
// and 'c'.
int cCount = 0;
// Traverse all characters of given string
for (int i = 0; i < s.length(); i++) {
/* If current character is 'a', then
there are following possibilities :
a) Current character begins a new
subsequence.
b) Current character is part of aCount
subsequences.
c) Current character is not part of
aCount subsequences. */
if (s.charAt(i) == 'a')
aCount = (1 + 2 * aCount);
/* If current character is 'b', then
there are following possibilities :
a) Current character begins a new
subsequence of b's with aCount
subsequences.
b) Current character is part of bCount
subsequences.
c) Current character is not part of
bCount subsequences. */
else if (s.charAt(i) == 'b')
bCount = (aCount + 2 * bCount);
/* If current character is 'c', then
there are following possibilities :
a) Current character begins a new
subsequence of c's with bCount
subsequences.
b) Current character is part of cCount
subsequences.
c) Current character is not part of
cCount subsequences. */
else if (s.charAt(i) == 'c')
cCount = (bCount + 2 * cCount);
}
return cCount;
}
// Driver code
public static void main(String args[])
{
String s = "abbc";
System.out.println(countSubsequences(s));
}
}
// This code is contributed by Sumit Ghosh
Python 3
# Python 3 program to count
# subsequences of the form
# a ^ i b ^ j c ^ k
# Returns count of subsequences
# of the form a ^ i b ^ j c ^ k
def countSubsequences(s):
# Initialize counts of different
# subsequences caused by different
# combination of 'a'
aCount = 0
# Initialize counts of different
# subsequences caused by different
# combination of 'a' and different
# combination of 'b'
bCount = 0
# Initialize counts of different
# subsequences caused by different
# combination of 'a', 'b' and 'c'.
cCount = 0
# Traverse all characters
# of given string
for i in range(len(s)):
# If current character is 'a',
# then there are following
# possibilities :
# a) Current character begins
# a new subsequence.
# b) Current character is part
# of aCount subsequences.
# c) Current character is not
# part of aCount subsequences.
if (s[i] == 'a'):
aCount = (1 + 2 * aCount)
# If current character is 'b', then
# there are following possibilities :
# a) Current character begins a
# new subsequence of b's with
# aCount subsequences.
# b) Current character is part
# of bCount subsequences.
# c) Current character is not
# part of bCount subsequences.
elif (s[i] == 'b'):
bCount = (aCount + 2 * bCount)
# If current character is 'c', then
# there are following possibilities :
# a) Current character begins a
# new subsequence of c's with
# bCount subsequences.
# b) Current character is part
# of cCount subsequences.
# c) Current character is not
# part of cCount subsequences.
elif (s[i] == 'c'):
cCount = (bCount + 2 * cCount)
return cCount
# Driver code
if __name__ == "__main__":
s = "abbc"
print(countSubsequences(s))
# This code is contributed
# by ChitraNayal
C#
// C# program to count subsequences
// of the form a^i b^j c^k
using System;
public class GFG {
// Returns count of subsequences
// of the form a^i b^j c^k
static int countSubsequences(String s)
{
// Initialize counts of different
// subsequences caused by different
// combination of 'a'
int aCount = 0;
// Initialize counts of different
// subsequences caused by different
// combination of 'a' and
// different combination of 'b'
int bCount = 0;
// Initialize counts of different
// subsequences caused by different
// combination of 'a', 'b' and 'c'
int cCount = 0;
// Traverse all characters of given string
for (int i = 0; i < s.Length; i++) {
// If current character is 'a', then
// there are following possibilities :
// a) Current character begins a
// new subsequence.
// b) Current character is part
// of aCount subsequences
// c) Current character is not part
// of aCount subsequences.
if (s[i] == 'a')
aCount = (1 + 2 * aCount);
// If current character is 'b', then
// there are following possibilities :
// a) Current character begins a new
// subsequence of b's with aCount
// subsequences.
// b) Current character is part of bCount
// subsequences.
// c) Current character is not part of
// bCount subsequences.
else if (s[i] == 'b')
bCount = (aCount + 2 * bCount);
// If current character is 'c', then
// there are following possibilities :
// a) Current character begins a new
// subsequence of c's with bCount
// subsequences.
// b) Current character is part of cCount
// subsequences.
// c) Current character is not part of
// cCount subsequences.
else if (s[i] == 'c')
cCount = (bCount + 2 * cCount);
}
return cCount;
}
// Driver code
public static void Main()
{
String s = "abbc";
Console.Write(countSubsequences(s));
}
}
// This code is contributed by Nitin Mittal.
PHP
Javascript
输出:
3
复杂度分析:
- 时间复杂度: O(n)。
需要对字符串一次遍历。 - 辅助空间: O(1)。
不需要额外的空间。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。