给定一个字符串S ,任务是仅使用索引在几何级数中的那些字符从S 中找到最大出现子序列P的计数。
注意:考虑 S 中基于 1 的索引。
例子 :
Input: S = “ddee”
Output: 4
Explanation:
If we take P = “de”, then P occurs 4 times in S. { {1, 3}, {1, 4}, {2, 3}, {2, 4} }
Input: S = “geeksforgeeks”
Output: 6
Explanation:
If we take P = “ek”, then P occurs 6 times in S. { {2, 4}, {3, 4}, {2, 12} {3, 12}, {10, 12}, {11, 12} }
原始的方法:我们的想法是产生给定字符串的所有可能的子序列,以使字符串的指标必须是几何级数。现在对于生成的每个子序列,找到每个子序列的出现次数并打印这些出现次数中的最大值。
时间复杂度: O(2 N )
辅助空间: O(1)
有效的方法:这个想法是观察任何子序列P可以是任何长度。假设 P = “abc” 并且它在 S 中出现 10 次(其中“abc”在 S 中的 GP 中有它们的索引),那么我们可以看到子序列“ab”(在 GP 中有索引)也将出现 10 次S。所以,为了简化解决方案,P 的可能长度将小于等于2。以下是步骤:
- 必须选择长度大于 1的子序列P ,因为如果 S 不只包含唯一字符,则长度大于 1 的P将比长度为 1的子序列出现更多的时间。
- 对于长度 1,计算字符串中每个字母的频率。
- 对于长度为 2 的二维数组dp[26][26] ,其中dp[i][j]告诉char(‘a’ + i) + char(‘a’ + j)字符串的频率。
- 步骤 2 中使用的递推关系由下式给出:
dp[i][j] = dp[i][j] + freq[i]
where,
freq[i] = frequency of character char(‘a’ + i)
dp[i][j] = frequency of string formed by current_character + char(‘a’ + i).
- 频率数组和数组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 现场工作专业课程和学生竞争性编程现场课程。