📌  相关文章
📜  仅使用索引在 GP 中的那些字符的最大出现子序列的计数

📅  最后修改于: 2021-09-17 16:18:17             🧑  作者: Mango

给定一个字符串S ,任务是仅使用索引在几何级数中的那些字符从S 中找到最大出现子序列P的计数。
注意:考虑 S 中基于 1 的索引。

例子 :

原始的方法:我们的想法是产生给定字符串的所有可能的子序列,以使字符串的指标必须是几何级数。现在对于生成的每个子序列,找到每个子序列的出现次数并打印这些出现次数中的最大值。

时间复杂度: O(2 N )
辅助空间: O(1)

有效的方法:这个想法是观察任何子序列P可以是任何长度。假设 P = “abc” 并且它在 S 中出现 10 次(其中“abc”在 S 中的 GP 中有它们的索引),那么我们可以看到子序列“ab”(在 GP 中有索引)也将出现 10 次S。所以,为了简化解决方案,P 的可能长度将小于等于2。以下是步骤:

  1. 必须选择长度大于 1的子序列P ,因为如果 S 不只包含唯一字符,则长度大于 1 的P将比长度为 1的子序列出现更多的时间。
  2. 对于长度 1,计算字符串中每个字母的频率。
  3. 对于长度为 2 的二维数组dp[26][26] ,其中dp[i][j]告诉char(‘a’ + i) + char(‘a’ + j)字符串的频率。
  4. 步骤 2 中使用的递推关系由下式给出:
  1. 频率数组和数组dp[][]的最大值给出给定字符串中任何子序列的最大计数。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count maximum occurring
// subsequence using only those characters
// whose indexes are in GP
int findMaxTimes(string S)
{
    long long int arr[26];
    long long int dp[26][26];
 
    // Initialize 1-D array and 2-D
    // dp array to 0
    memset(arr, 0, sizeof(arr));
    memset(dp, 0, sizeof(dp));
 
    // Iterate till the length of
    // the given string
    for (int i = 0; i < S.size(); i++) {
        int now = S[i] - 'a';
        for (int j = 0; j < 26; j++) {
            dp[j][now] += arr[j];
        }
        arr[now]++;
    }
 
    long long int ans = 0;
 
    // Update ans for 1-length subsequence
    for (int i = 0; i < 26; i++)
        ans = max(ans, arr[i]);
 
    // Update ans for 2-length subsequence
    for (int i = 0; i < 26; i++) {
        for (int j = 0; j < 26; j++) {
            ans = max(ans, dp[i][j]);
        }
    }
 
    // Return the answer
    return ans;
}
 
// Driver Code
int main()
{
    // Given string s
    string S = "ddee";
 
    // Function Call
    cout << findMaxTimes(S);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to count maximum occurring
// subsequence using only those characters
// whose indexes are in GP
static int findMaxTimes(String S)
{
    int []arr = new int[26];
    int [][]dp = new int[26][26];
 
    // Iterate till the length of
    // the given String
    for(int i = 0; i < S.length(); i++)
    {
        int now = S.charAt(i) - 'a';
        for(int j = 0; j < 26; j++)
        {
            dp[j][now] += arr[j];
        }
        arr[now]++;
    }
 
    int ans = 0;
 
    // Update ans for 1-length subsequence
    for(int i = 0; i < 26; i++)
        ans = Math.max(ans, arr[i]);
 
    // Update ans for 2-length subsequence
    for(int i = 0; i < 26; i++)
    {
        for(int j = 0; j < 26; j++)
        {
            ans = Math.max(ans, dp[i][j]);
        }
    }
 
    // Return the answer
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given String s
    String S = "ddee";
 
    // Function call
    System.out.print(findMaxTimes(S));
}
}
 
// This code is contributed by Amit Katiyar


Python3
# Python3 program for the above approach
 
# Function to count maximum occurring
# subsequence using only those characters
# whose indexes are in GP
def findMaxTimes(S):
 
    # Initialize 1-D array and 2-D
    # dp array to 0
    arr = [0] * 26
    dp = [[0 for x in range(26)]
             for y in range(26)]
 
    # Iterate till the length of
    # the given string
    for i in range(len(S)):
        now = ord(S[i]) - ord('a')
         
        for j in range(26):
            dp[j][now] += arr[j]
 
        arr[now] += 1
 
    ans = 0
 
    # Update ans for 1-length subsequence
    for i in range(26):
        ans = max(ans, arr[i])
 
    # Update ans for 2-length subsequence
    for i in range(26):
        for j in range(26):
            ans = max(ans, dp[i][j])
 
    # Return the answer
    return ans
 
# Driver Code
 
# Given string s
S = "ddee"
 
# Function call
print(findMaxTimes(S))
 
# This code is contributed by Shivam Singh


C#
// C# program for the above approach
using System;
class GFG{
 
// Function to count maximum occurring
// subsequence using only those characters
// whose indexes are in GP
static int findMaxTimes(String S)
{
    int []arr = new int[26];
    int [,]dp = new int[26, 26];
 
    // Iterate till the length of
    // the given String
    for(int i = 0; i < S.Length; i++)
    {
        int now = S[i] - 'a';
        for(int j = 0; j < 26; j++)
        {
            dp[j, now] += arr[j];
        }
        arr[now]++;
    }
 
    int ans = 0;
 
    // Update ans for 1-length subsequence
    for(int i = 0; i < 26; i++)
        ans = Math.Max(ans, arr[i]);
 
    // Update ans for 2-length subsequence
    for(int i = 0; i < 26; i++)
    {
        for(int j = 0; j < 26; j++)
        {
            ans = Math.Max(ans, dp[i, j]);
        }
    }
 
    // Return the answer
    return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given String s
    String S = "ddee";
 
    // Function call
    Console.Write(findMaxTimes(S));
}
}
 
// This code is contributed by gauravrajput1


Javascript


输出:
4

时间复杂度: O(max(N*26, 26 * 26))
辅助空间: O(26 * 26)

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