📜  计算不同的子序列

📅  最后修改于: 2021-04-26 19:02:59             🧑  作者: Mango

给定一个字符串,找到它的不同子序列的计数。

例子:

Input  : str = "gfg"
Output : 7
The seven distinct subsequences are "", "g", "f",
"gf", "fg", "gg" and "gfg" 

Input  : str = "ggg"
Output : 4
The four distinct subsequences are "", "g", "gg"
and "ggg"

如果输入字符串的所有字符都不同,则计数不同子序列的问题很容易。该计数等于n C 0 + n C 1 + n C 2 +… n C n = 2 n
当输入字符串可以重复时,如何计算不同的子序列?
计算具有重复项的字符串不同子序列的简单解决方案是生成所有子序列。对于每个子序列,如果尚不存在,则将其存储在哈希表中。该解决方案的时间复杂度是指数级的,并且需要指数级的额外空间。

方法1(朴素的方法):使用一组(没有动态编程)

方法:生成给定字符串的所有可能的子序列。字符串可以通过以下方式生成:
a)在输出数组中包含一个特定元素(例如ith ),并为其余的输入字符串递归调用该函数。这导致具有i字符的字符串的子序列。
b)排除特定元素(例如ith ),并为其余的输入字符串递归调用该函数。它包含所有不具有第i字符的子序列。
生成子序列后,在函数的基本情况下,我们将生成的子序列插入无序集合中。无序集合是一种数据结构,它以无序的方式存储不同的元素。这样,我们将所有生成的子序列插入到集合中,并打印集合的大小作为我们的答案,因为最后,集合将仅包含不同的子序列。

C++
// C++ program to print distinct
// subsequences of a given string
#include 
using namespace std;
 
// Create an empty set to store the subsequences
unordered_set sn;
 
// Function for generating the subsequences
void subsequences(char s[], char op[], int i, int j)
{
 
    // Base Case
    if (s[i] == '\0') {
        op[j] = '\0';
 
        // Insert each generated
        // subsequence into the set
        sn.insert(op);
        return;
    }
 
    // Recursive Case
    else {
        // When a particular character is taken
        op[j] = s[i];
        subsequences(s, op, i + 1, j + 1);
 
        // When a particular character isn't taken
        subsequences(s, op, i + 1, j);
        return;
    }
}
 
// Driver Code
int main()
{
    char str[] = "ggg";
    int m = sizeof(str) / sizeof(char);
    int n = pow(2, m) + 1;
 
    // Output array for storing
    // the generating subsequences
    // in each call
    char op[n];
 
    // Function Call
    subsequences(str, op, 0, 0);
 
    // Output will be the number
    // of elements in the set
    cout << sn.size();
    sn.clear();
    return 0;
 
    // This code is contributed by Kishan Mishra
}


Python3
# Python3 program to print
# distinct subsequences of
# a given string
import math
 
# Create an empty set
# to store the subsequences
sn = []
global m
m = 0
 
# Function for generating
# the subsequences
def subsequences(s, op, i, j):
 
    # Base Case
    if(i == m):
        op[j] = None
        temp = "".join([i for i in op if i] )
 
        # Insert each generated
        # subsequence into the set
        sn.append(temp)
        return
      
    # Recursive Case
    else:
 
        # When a particular
        # character is taken
        op[j] = s[i]
 
        subsequences(s, op,
                     i + 1, j + 1)
 
        # When a particular
        # character isn't taken
        subsequences(s, op,
                     i + 1, j)
        return
 
# Driver Code
str = "ggg"
m = len(str)
n = int(math.pow(2, m) + 1)
 
# Output array for storing
# the generating subsequences
# in each call
op = [None for i in range(n)]
 
# Function Call
subsequences(str, op, 0, 0)
 
# Output will be the number
#of elements in the set
print(len(set(sn)))
 
# This code is contributed by avanitrachhadiya2155


C++
// C++ program to count number of distinct
// subsequences of a given string.
#include 
using namespace std;
const int MAX_CHAR = 256;
 
// Returns count of distinct sunsequences of str.
int countSub(string str)
{
    // Create an array to store index
    // of last
    vector last(MAX_CHAR, -1);
 
    // Length of input string
    int n = str.length();
 
    // dp[i] is going to store count of distinct
    // subsequences of length i.
    int dp[n + 1];
 
    // Empty substring has only one subsequence
    dp[0] = 1;
 
    // Traverse through all lengths from 1 to n.
    for (int i = 1; i <= n; i++) {
        // Number of subsequences with substring
        // str[0..i-1]
        dp[i] = 2 * dp[i - 1];
 
        // If current character has appeared
        // before, then remove all subsequences
        // ending with previous occurrence.
        if (last[str[i - 1]] != -1)
            dp[i] = dp[i] - dp[last[str[i - 1]]];
 
        // Mark occurrence of current character
        last[str[i - 1]] = (i - 1);
    }
 
    return dp[n];
}
 
// Driver code
int main()
{
    cout << countSub("gfg");
    return 0;
}


Java
// Java program to count number of distinct
// subsequences of a given string.
import java.util.ArrayList;
import java.util.Arrays;
public class Count_Subsequences {
 
    static final int MAX_CHAR = 256;
 
    // Returns count of distinct sunsequences of str.
    static int countSub(String str)
    {
        // Create an array to store index
        // of last
        int[] last = new int[MAX_CHAR];
        Arrays.fill(last, -1);
 
        // Length of input string
        int n = str.length();
 
        // dp[i] is going to store count of distinct
        // subsequences of length i.
        int[] dp = new int[n + 1];
 
        // Empty substring has only one subsequence
        dp[0] = 1;
 
        // Traverse through all lengths from 1 to n.
        for (int i = 1; i <= n; i++) {
            // Number of subsequences with substring
            // str[0..i-1]
            dp[i] = 2 * dp[i - 1];
 
            // If current character has appeared
            // before, then remove all subsequences
            // ending with previous occurrence.
            if (last[(int)str.charAt(i - 1)] != -1)
                dp[i] = dp[i] - dp[last[(int)str.charAt(i - 1)]];
 
            // Mark occurrence of current character
            last[(int)str.charAt(i - 1)] = (i - 1);
        }
 
        return dp[n];
    }
 
    // Driver code
    public static void main(String args[])
    {
        System.out.println(countSub("gfg"));
    }
}
// This code is contributed by Sumit Ghosh


Python3
# Python3 program to count number of
# distinct subseqences of a given string
 
MAX_CHAR = 256
 
def countSub(ss):
 
    # create an array to store index of last
    last = [-1 for i in range(MAX_CHAR + 1)]
     
    # length of input string
    n = len(ss)
     
    # dp[i] is going to store count of
    # discount subsequence of length of i
    dp = [-2 for i in range(n + 1)]
      
    # empty substring has only
    # one subseqence
    dp[0] = 1
     
    # Traverse through all lengths
    # from 1 to n
    for i in range(1, n + 1):
         
        # number of subseqence with
        # substring str[0...i-1]
        dp[i] = 2 * dp[i - 1]
 
        # if current character has appeared
        # before, then remove all subseqences
        # ending with previous occurrence.
        if last[ord(ss[i - 1])] != -1:
            dp[i] = dp[i] - dp[last[ord(ss[i - 1])]]
        last[ord(ss[i - 1])] = i - 1
     
    return dp[n]
     
# Driver code
print(countSub("gfg"))
 
# This code is contributed
# by mohit kumar 29


C#
// C# program to count number of distinct
// subsequences of a given string.
using System;
 
public class Count_Subsequences {
 
    static readonly int MAX_CHAR = 256;
 
    // Returns count of distinct sunsequences of str.
    static int countSub(String str)
    {
        // Create an array to store index
        // of last
        int[] last = new int[MAX_CHAR];
 
        for (int i = 0; i < MAX_CHAR; i++)
            last[i] = -1;
 
        // Length of input string
        int n = str.Length;
 
        // dp[i] is going to store count of
        // distinct subsequences of length i.
        int[] dp = new int[n + 1];
 
        // Empty substring has only one subsequence
        dp[0] = 1;
 
        // Traverse through all lengths from 1 to n.
        for (int i = 1; i <= n; i++) {
            // Number of subsequences with substring
            // str[0..i-1]
            dp[i] = 2 * dp[i - 1];
 
            // If current character has appeared
            // before, then remove all subsequences
            // ending with previous occurrence.
            if (last[(int)str[i - 1]] != -1)
                dp[i] = dp[i] - dp[last[(int)str[i - 1]]];
 
            // Mark occurrence of current character
            last[(int)str[i - 1]] = (i - 1);
        }
        return dp[n];
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        Console.WriteLine(countSub("gfg"));
    }
}
 
// This code is contributed 29AjayKumar


Javascript


C++
// C++ program for above approach
#include 
using namespace std;
 
// Returns count of distinct
// subsequences of str.
int countSub(string s)
{
    map Map;
 
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.length(); i++)
    {
        Map[s[i]] = -1;
    }
      
    int allCount = 0;
    int levelCount = 0;
      
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.length(); i++)
    {
        char c = s[i];
         
        // Check if i equal to 0
        if (i == 0)
        {
            allCount = 1;
            Map = 1;
            levelCount = 1;
            continue;
        }
         
        // Replace levelCount withe
        // allCount + 1
        levelCount = allCount + 1;
         
        // If map is less than 0
        if (Map < 0)
        {
            allCount = allCount + levelCount;
        }
        else
        {
            allCount = allCount +
                     levelCount - Map;
        }
        Map = levelCount;
    }
     
    // Return answer
    return allCount;
}
 
// Driver code
int main()
{
    string list[] = { "abab", "gfg" };
      
    for(string s : list)
    {
        int cnt = countSub(s);
        int withEmptyString = cnt + 1;
         
        cout << "With empty string count for "
             << s << " is " << withEmptyString
             << endl;
        cout << "Without empty string count for "
             << s << " is " << cnt << endl;
    }
    return 0;
}
 
// This code is contributed by divyeshrabadiya07


Java
// Java Program for above approach
import java.io.*;
import java.util.*;
class SubsequenceCount
{
 
  // Returns count of distinct
  // subsequences of str.
  public static int countSub(String s)
  {
    HashMap map = new HashMap();
 
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.length(); i++)
    {
      map.put(s.charAt(i), -1);
    }
     
    int allCount = 0;
    int levelCount = 0;
     
    // Iterate from 0 to s.length()
    for(int i=0;i list = Arrays.asList("abab","gfg");
     
    for(String s : list)
    {
      int cnt = countSub(s);
      int withEmptyString = cnt+1;
      System.out.println("With empty string count for " +
                         s +" is " + withEmptyString);
      System.out.println("Without empty string count for " +
                         s + " is " + cnt);
    }
  }
}
//Code is contributed by abhisht7


Python3
# Python3 program for above approach
 
# Returns count of distinct 
# subsequences of str.
def countSub(s):
     
    Map = {}
 
    # Iterate from 0 to length of s
    for i in range(len(s)):
        Map[s[i]] = -1
 
    allCount = 0
    levelCount = 0
 
    # Iterate from 0 to length of s
    for i in range(len(s)):
        c = s[i]
 
        # Check if i equal to 0
        if (i == 0):
            allCount = 1
            Map = 1
            levelCount = 1
            continue
 
        # Replace levelCount withe
          # allCount + 1
        levelCount = allCount + 1
 
        # If map is less than 0
        if (Map < 0):
            allCount = allCount + levelCount
        else:
            allCount = allCount + levelCount - Map
 
        Map = levelCount
 
    # Return answer
    return allCount
 
# Driver Code
List = [ "abab", "gfg" ]
 
for s in List:
    cnt = countSub(s)
    withEmptyString = cnt + 1
 
    print("With empty string count for",
          s, "is", withEmptyString)
    print("Without empty string count for",
          s, "is", cnt)
 
# This code is contributed by rag2127


C#
// C# Program for above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Returns count of distinct
// subsequences of str.
public static int countSub(String s)
{
    Dictionary map = new Dictionary(); 
                                          
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.Length; i++)
    {
        if (!map.ContainsKey(s[i]))
        {
            map.Add(s[i], -1);
        }
    }
     
    int allCount = 0;
    int levelCount = 0;
     
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.Length; i++)
    {
        char c = s[i];
         
        // Check if i equal to 0
        if (i == 0)
        {
            allCount = 1;
            if (!map.ContainsKey(c))
            {
                map.Add(c, 1);
            }
            else
            {
                map = 1;
            }
            levelCount = 1;
            continue;
        }
         
        // Replace levelCount withe
        // allCount + 1
        levelCount = allCount + 1;
         
        // If map is less than 0
        if (map.ContainsKey(c))
        {
            if (map < 0)
            {
                allCount = (allCount + levelCount);
            }
            else
            {
                allCount = (allCount +
                          levelCount - map);
            }
        }
         
        if (!map.ContainsKey(c))
        {
            map.Add(c, levelCount);
        }
        else
        {
            map = levelCount;
        }
    }
     
    // Return answer
    return allCount;
 
}
 
// Driver Code
static void Main()
{
    List list = new List();
    list.Add("abab");
    list.Add("gfg");
  
    foreach(string s in list)
    {
        int cnt = countSub(s);
        int withEmptyString = cnt + 1;
         
        Console.WriteLine("With empty string count for " +
                          s + " is " + withEmptyString);
        Console.WriteLine("Without empty string count for " +
                          s + " is " + cnt);
    }
}
}
 
// This code is contributed by divyesh072019


输出:
4

时间复杂度:O(2 ^ n)
腋窝空间: O(n)
其中n是字符串的长度。

方法2(有效方法):使用动态编程

高效解决方案不需要生成子序列。

Let countSub(n) be count of subsequences of 
first n characters in input string. We can
recursively write it as below. 

countSub(n) = 2*Count(n-1) - Repetition

If current character, i.e., str[n-1] of str has
not appeared before, then 
   Repetition = 0

Else:
   Repetition  =  Count(m)
   Here m is index of previous occurrence of
   current character. We basically remove all
   counts ending with previous occurrence of
   current character.

这是如何运作的?
如果没有重复,则对n-1而言,计数将变为计数的两倍,这是因为我们通过在所有可能具有n-1长度的子序列的末尾添加当前字符获得count(n-1)个更多的子序列。
如果存在重复,则我们找到所有以上一个事件结尾的不同子序列的计数。可以通过递归调用前一次出现的索引来获得此计数。
由于上述重复存在重叠的子问题,因此我们可以使用动态编程来解决。

以下是上述想法的实现。

C++

// C++ program to count number of distinct
// subsequences of a given string.
#include 
using namespace std;
const int MAX_CHAR = 256;
 
// Returns count of distinct sunsequences of str.
int countSub(string str)
{
    // Create an array to store index
    // of last
    vector last(MAX_CHAR, -1);
 
    // Length of input string
    int n = str.length();
 
    // dp[i] is going to store count of distinct
    // subsequences of length i.
    int dp[n + 1];
 
    // Empty substring has only one subsequence
    dp[0] = 1;
 
    // Traverse through all lengths from 1 to n.
    for (int i = 1; i <= n; i++) {
        // Number of subsequences with substring
        // str[0..i-1]
        dp[i] = 2 * dp[i - 1];
 
        // If current character has appeared
        // before, then remove all subsequences
        // ending with previous occurrence.
        if (last[str[i - 1]] != -1)
            dp[i] = dp[i] - dp[last[str[i - 1]]];
 
        // Mark occurrence of current character
        last[str[i - 1]] = (i - 1);
    }
 
    return dp[n];
}
 
// Driver code
int main()
{
    cout << countSub("gfg");
    return 0;
}

Java

// Java program to count number of distinct
// subsequences of a given string.
import java.util.ArrayList;
import java.util.Arrays;
public class Count_Subsequences {
 
    static final int MAX_CHAR = 256;
 
    // Returns count of distinct sunsequences of str.
    static int countSub(String str)
    {
        // Create an array to store index
        // of last
        int[] last = new int[MAX_CHAR];
        Arrays.fill(last, -1);
 
        // Length of input string
        int n = str.length();
 
        // dp[i] is going to store count of distinct
        // subsequences of length i.
        int[] dp = new int[n + 1];
 
        // Empty substring has only one subsequence
        dp[0] = 1;
 
        // Traverse through all lengths from 1 to n.
        for (int i = 1; i <= n; i++) {
            // Number of subsequences with substring
            // str[0..i-1]
            dp[i] = 2 * dp[i - 1];
 
            // If current character has appeared
            // before, then remove all subsequences
            // ending with previous occurrence.
            if (last[(int)str.charAt(i - 1)] != -1)
                dp[i] = dp[i] - dp[last[(int)str.charAt(i - 1)]];
 
            // Mark occurrence of current character
            last[(int)str.charAt(i - 1)] = (i - 1);
        }
 
        return dp[n];
    }
 
    // Driver code
    public static void main(String args[])
    {
        System.out.println(countSub("gfg"));
    }
}
// This code is contributed by Sumit Ghosh

Python3

# Python3 program to count number of
# distinct subseqences of a given string
 
MAX_CHAR = 256
 
def countSub(ss):
 
    # create an array to store index of last
    last = [-1 for i in range(MAX_CHAR + 1)]
     
    # length of input string
    n = len(ss)
     
    # dp[i] is going to store count of
    # discount subsequence of length of i
    dp = [-2 for i in range(n + 1)]
      
    # empty substring has only
    # one subseqence
    dp[0] = 1
     
    # Traverse through all lengths
    # from 1 to n
    for i in range(1, n + 1):
         
        # number of subseqence with
        # substring str[0...i-1]
        dp[i] = 2 * dp[i - 1]
 
        # if current character has appeared
        # before, then remove all subseqences
        # ending with previous occurrence.
        if last[ord(ss[i - 1])] != -1:
            dp[i] = dp[i] - dp[last[ord(ss[i - 1])]]
        last[ord(ss[i - 1])] = i - 1
     
    return dp[n]
     
# Driver code
print(countSub("gfg"))
 
# This code is contributed
# by mohit kumar 29

C#

// C# program to count number of distinct
// subsequences of a given string.
using System;
 
public class Count_Subsequences {
 
    static readonly int MAX_CHAR = 256;
 
    // Returns count of distinct sunsequences of str.
    static int countSub(String str)
    {
        // Create an array to store index
        // of last
        int[] last = new int[MAX_CHAR];
 
        for (int i = 0; i < MAX_CHAR; i++)
            last[i] = -1;
 
        // Length of input string
        int n = str.Length;
 
        // dp[i] is going to store count of
        // distinct subsequences of length i.
        int[] dp = new int[n + 1];
 
        // Empty substring has only one subsequence
        dp[0] = 1;
 
        // Traverse through all lengths from 1 to n.
        for (int i = 1; i <= n; i++) {
            // Number of subsequences with substring
            // str[0..i-1]
            dp[i] = 2 * dp[i - 1];
 
            // If current character has appeared
            // before, then remove all subsequences
            // ending with previous occurrence.
            if (last[(int)str[i - 1]] != -1)
                dp[i] = dp[i] - dp[last[(int)str[i - 1]]];
 
            // Mark occurrence of current character
            last[(int)str[i - 1]] = (i - 1);
        }
        return dp[n];
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        Console.WriteLine(countSub("gfg"));
    }
}
 
// This code is contributed 29AjayKumar

Java脚本


输出:

7

时间复杂度: O(n)
辅助空间: O(n)

方法3:没有多余的空间

比方说,我们有2个变量:`allCount`将总计不同的子序列数相加,以及`levelCount`存储以索引i结尾的子序列数。为了查找重复,我们将为每个字符存储最新的levelCount。最后,我们将看到如何使用`levelCount`变量确定`allCount`。

这是上述陈述的表示:

说s =“ abab”

让我们使用-1初始化映射中的所有字符串字符。此映射图中的值表示在此字符的最后一次出现时结束了多少个不同的子序列。

地图= {a:-1,b:-1}

最初我们也有

levelCount = 0;

allCount = 0;

现在遍历每个字符

第一次迭代“ a”

以’a’结尾的不同子序列是:“ a”。因此,我们使levelCount = 1,现在allCount也为1。
地图将更新为map [`current_char`] = levelCount。

levelCount = 1; allCount = 1;地图= {a:1,b:-1}

第二次迭代’b’

以“ b”结尾的不同子序列是“ ab”,“ b”。因此,levelCount = 2。

到目前为止,我们发现的子序列总数也为3。allCount = 3。

在这里我们可以注意到,可以通过将allCount变量的最后一个值加1来确定levelCount

levelCount = allCount + 1(levelCount = 1 + 1 = 2)

如果这是一个不同的字符,那么当前的allCount也可以很容易地确定为

allCount = allCount + levelCount; (allCount = 1+ 2 = 3)

我们还使用当前角色的levelCount更新地图。地图{a:1,b:2}

第3次迭代“ a”

现在我们有一个重复。

以“ a”结尾的不同子序列现在为“ aa”,“ ba”,“ aba”,“ a”。因此我们的levelCount现在为4:如前所述,由allCount + 1 = 3 + 1 = 4确定。

如果这是一个不同的字符allcount应该是7(allCount = allCount + levelCount = 3 + 4),但是我们将删除重复,即map.get(`a`)为1,所以现在allCount是7- 1 = 6

在此请注意,我们实质上已删除了第一个迭代的结果,该结果是重复的子序列“ a”。这仅意味着我们可以形成与以旧的`a`形成的新建立的`a’相同的子序列,因此我们减去了较旧的子序列。

现在使用新的levelCount将地图更新为{a:4,b:2}

在重复的情况下,allCount计算将更改为

allCount = allCount + levelCount – map.get(currentCharacter);

allCount = 3 + 4-1 = 6

第4次迭代“ b”

再次重复。

现在,以“ b”结尾的子序列为“ abb”,“ bb”,“ aab”,“ bab”,“ abab”,“ ab”,“ b”,其计数与levelCount = allCount + 1 = 6 + 1 = 7。

allCount将是= allCount + levelCount – map.get(’b’)= 6 + 7-2 = 11

不同子序列的总数为allCount。

如果还包括空字符串,那么我们的答案是allCount + 1。

下面是上述方法的实现。

C++

// C++ program for above approach
#include 
using namespace std;
 
// Returns count of distinct
// subsequences of str.
int countSub(string s)
{
    map Map;
 
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.length(); i++)
    {
        Map[s[i]] = -1;
    }
      
    int allCount = 0;
    int levelCount = 0;
      
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.length(); i++)
    {
        char c = s[i];
         
        // Check if i equal to 0
        if (i == 0)
        {
            allCount = 1;
            Map = 1;
            levelCount = 1;
            continue;
        }
         
        // Replace levelCount withe
        // allCount + 1
        levelCount = allCount + 1;
         
        // If map is less than 0
        if (Map < 0)
        {
            allCount = allCount + levelCount;
        }
        else
        {
            allCount = allCount +
                     levelCount - Map;
        }
        Map = levelCount;
    }
     
    // Return answer
    return allCount;
}
 
// Driver code
int main()
{
    string list[] = { "abab", "gfg" };
      
    for(string s : list)
    {
        int cnt = countSub(s);
        int withEmptyString = cnt + 1;
         
        cout << "With empty string count for "
             << s << " is " << withEmptyString
             << endl;
        cout << "Without empty string count for "
             << s << " is " << cnt << endl;
    }
    return 0;
}
 
// This code is contributed by divyeshrabadiya07

Java

// Java Program for above approach
import java.io.*;
import java.util.*;
class SubsequenceCount
{
 
  // Returns count of distinct
  // subsequences of str.
  public static int countSub(String s)
  {
    HashMap map = new HashMap();
 
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.length(); i++)
    {
      map.put(s.charAt(i), -1);
    }
     
    int allCount = 0;
    int levelCount = 0;
     
    // Iterate from 0 to s.length()
    for(int i=0;i list = Arrays.asList("abab","gfg");
     
    for(String s : list)
    {
      int cnt = countSub(s);
      int withEmptyString = cnt+1;
      System.out.println("With empty string count for " +
                         s +" is " + withEmptyString);
      System.out.println("Without empty string count for " +
                         s + " is " + cnt);
    }
  }
}
//Code is contributed by abhisht7

Python3

# Python3 program for above approach
 
# Returns count of distinct 
# subsequences of str.
def countSub(s):
     
    Map = {}
 
    # Iterate from 0 to length of s
    for i in range(len(s)):
        Map[s[i]] = -1
 
    allCount = 0
    levelCount = 0
 
    # Iterate from 0 to length of s
    for i in range(len(s)):
        c = s[i]
 
        # Check if i equal to 0
        if (i == 0):
            allCount = 1
            Map = 1
            levelCount = 1
            continue
 
        # Replace levelCount withe
          # allCount + 1
        levelCount = allCount + 1
 
        # If map is less than 0
        if (Map < 0):
            allCount = allCount + levelCount
        else:
            allCount = allCount + levelCount - Map
 
        Map = levelCount
 
    # Return answer
    return allCount
 
# Driver Code
List = [ "abab", "gfg" ]
 
for s in List:
    cnt = countSub(s)
    withEmptyString = cnt + 1
 
    print("With empty string count for",
          s, "is", withEmptyString)
    print("Without empty string count for",
          s, "is", cnt)
 
# This code is contributed by rag2127

C#

// C# Program for above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Returns count of distinct
// subsequences of str.
public static int countSub(String s)
{
    Dictionary map = new Dictionary(); 
                                          
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.Length; i++)
    {
        if (!map.ContainsKey(s[i]))
        {
            map.Add(s[i], -1);
        }
    }
     
    int allCount = 0;
    int levelCount = 0;
     
    // Iterate from 0 to s.length()
    for(int i = 0; i < s.Length; i++)
    {
        char c = s[i];
         
        // Check if i equal to 0
        if (i == 0)
        {
            allCount = 1;
            if (!map.ContainsKey(c))
            {
                map.Add(c, 1);
            }
            else
            {
                map = 1;
            }
            levelCount = 1;
            continue;
        }
         
        // Replace levelCount withe
        // allCount + 1
        levelCount = allCount + 1;
         
        // If map is less than 0
        if (map.ContainsKey(c))
        {
            if (map < 0)
            {
                allCount = (allCount + levelCount);
            }
            else
            {
                allCount = (allCount +
                          levelCount - map);
            }
        }
         
        if (!map.ContainsKey(c))
        {
            map.Add(c, levelCount);
        }
        else
        {
            map = levelCount;
        }
    }
     
    // Return answer
    return allCount;
 
}
 
// Driver Code
static void Main()
{
    List list = new List();
    list.Add("abab");
    list.Add("gfg");
  
    foreach(string s in list)
    {
        int cnt = countSub(s);
        int withEmptyString = cnt + 1;
         
        Console.WriteLine("With empty string count for " +
                          s + " is " + withEmptyString);
        Console.WriteLine("Without empty string count for " +
                          s + " is " + cnt);
    }
}
}
 
// This code is contributed by divyesh072019

输出:

With empty string count for abab is 12
Without empty string count for abab is 11
With empty string count for gfg is 7
Without empty string count for gfg is 6

时间复杂度:O(n)

空间复杂度: O(1)