📜  计算不同的子序列

📅  最后修改于: 2021-09-17 16:04:38             🧑  作者: 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(Naive Approach):使用集合(不使用动态规划)

方法:生成给定字符串的所有可能子序列。字符串可以通过以下方式生成:
a)在输出数组中包含一个特定的元素(比如 i th ),并递归地为输入字符串的其余部分调用该函数。这导致具有i字符的字符串的子序列。
b)排除特定元素(比如 i th )并递归调用该函数以获取输入字符串的其余部分。这包含所有没有第 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


Javascript


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


Javascript


输出:
4

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

方法二(Efficient Approach):使用动态规划

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

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

蟒蛇3

# 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


输出:

7

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

方法三:没有多余的空间

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

以下是上述语句的表示:

说 s = “abab”

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

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

最初我们也有

levelCount=0;

所有计数 = 0;

现在遍历每个字符

第一次迭代’a’

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

级别计数 = 1;所有计数 = 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; (所有计数= 1+ 2 = 3)

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

第三次迭代’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”会形成,所以我们减去旧的子序列。

地图现在更新了 a 到 {a:4,b:2} 的新 levelCount

如果重复出 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

蟒蛇3

# 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

Javascript


输出:

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)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程