给定一个字符串,计数形式为a i b j c k的子序列,即由i’a’个字符,后跟j’b’个字符,后跟k个’c’个字符,其中i> = 1, j> = 1且k> = 1。
注意:如果为两个子序列选取的数组索引的集合不同,则认为两个子序列是不同的。
预期时间复杂度: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”的不同组合引起的不同子序列的计数。让此计数为aCount。
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表示我们没有使用该字符)。还请注意,这与两者之间的字符无关,即aaa和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)。
不需要额外的空间。