Open In App

Optimizing Arithmetic Progressions in Subsequences

Given a string S, a string T is considered good if following 2 conditions hold:

For example, if S = “aaabb” then T = “aab” is good because T is subsequence of S at indices 1,3,5 which is an arithmetic progression. The task is to determine any subsequence that is good string having highest occurrences in the string. Print the number of times that subsequence appears as a good string in the given string.



Examples:

Input: S = “aaabb”
Output: 6
Explanation: “ab” is the good strings with the highest number of occurrences. “ab” occurred 6 times at (1,4), (1,5), (2,4), (2,5), (3,4) and (3,5)



Input: “abcde”
Output: 1
Explanation: “a” is the good string which occurred only once.

Observations:

We observe that if the good string that occurs the most times has length > 2, then there must exist one that occurs just as many times of length exactly 2. This is true because we can always just take the first 2 letters of the good string and still get the answer. Therefore, we only need to check strings of lengths 1 and 2.

Approach: The problem can be solved using the following approach:

The intuition is based on the properties of subsequences and arithmetic progressions. Here’s the key idea:

  • The problem asks for a good subsequence, which is defined as a subsequence where the indices form an arithmetic progression. This means that the characters in the subsequence are evenly spaced in the original string.
  • Count the frequency of each character and each pair of characters in the string. we’ll use two arrays, arr1 and arr2, to store these frequencies. arr1 is the frequency of character c, and arr2[i][j] is the frequency of pairs of characters i and j where j appears after i in the string.
  • Now, iterate over the string and for each character, updates the frequency of that character and all pairs that can be formed with that character. After that, finds the maximum frequency among all characters and all pairs of characters. This maximum frequency is the number of times the most frequent good subsequence appears in the string.

This approach will work because a good subsequence can be either a single character or a pair of characters. A single character is always a good subsequence, and a pair of characters is a good subsequence if and only if the two characters appear at indices that form an arithmetic progression. By counting the frequency of each character and each pair of characters, the code effectively counts the frequency of all possible good subsequences.

Steps to solve the problem:

Below is the implementation of the above approach:




#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
 
// Declare arrays to store the frequency of characters and
// pairs of characters
ll arr1[26], arr2[26][26];
 
int main()
{
    string S = "aaabb";
 
    // Iterate over the string
    for (int i = 0; i < S.length(); i++) {
 
        // Convert the current character to its
        // corresponding index (0-25)
        int c = S[i] - 'a';
 
        // For each character, add its frequency to the
        // count of pairs with the current character
        for (int j = 0; j < 26; j++)
            arr2[j] += arr1[j];
 
        // Increment the frequency of the current character
        arr1++;
    }
 
    // Initialize the maximum frequency to 0
    ll ans = 0;
 
    // Find the maximum frequency among all characters
    for (int i = 0; i < 26; i++)
        ans = max(ans, arr1[i]);
 
    // Find the maximum frequency among all pairs of
    // characters
    for (int i = 0; i < 26; i++)
        for (int j = 0; j < 26; j++)
            ans = max(ans, arr2[i][j]);
 
    cout << ans << endl; // Print the maximum frequency
}




import java.util.*;
public class GFG {
    public static void main(String[] args)
    {
        String S = "aaabb";
 
        // Declare arrays to store the frequency of
        // characters and pairs of characters
        long[] arr1 = new long[26];
        long[][] arr2 = new long[26][26];
 
        // Iterate over the string
        for (int i = 0; i < S.length(); i++) {
 
            // Convert the current character to its
            // corresponding index (0-25)
            int c = S.charAt(i) - 'a';
 
            // For each character, add its frequency to the
            // count of pairs with the current character
            for (int j = 0; j < 26; j++)
                arr2[j] += arr1[j];
 
            // Increment the frequency of the current
            // character
            arr1++;
        }
 
        // Initialize the maximum frequency to 0
        long ans = 0;
 
        // Find the maximum frequency among all characters
        for (int i = 0; i < 26; i++)
            ans = Math.max(ans, arr1[i]);
 
        // Find the maximum frequency among all pairs of
        // characters
        for (int i = 0; i < 26; i++)
            for (int j = 0; j < 26; j++)
                ans = Math.max(ans, arr2[i][j]);
 
        System.out.println(
            ans); // Print the maximum frequency
    }
}




# Initialize arrays to store the frequency of characters and pairs of characters
arr1 = [0] * 26
arr2 = [[0] * 26 for _ in range(26)]
 
# Input string
S = "aaabb"
 
# Iterate over the string
for i in range(len(S)):
    # Convert the current character to its corresponding index (0-25)
    c = ord(S[i]) - ord('a')
 
    # For each character, add its frequency to the count of pairs with the current character
    for j in range(26):
        arr2[j] += arr1[j]
 
    # Increment the frequency of the current character
    arr1 += 1
 
# Initialize the maximum frequency to 0
ans = 0
 
# Find the maximum frequency among all characters
for i in range(26):
    ans = max(ans, arr1[i])
 
# Find the maximum frequency among all pairs of characters
for i in range(26):
    for j in range(26):
        ans = max(ans, arr2[i][j])
 
print(ans)  # Print the maximum frequency




using System;
 
class GFG {
    public static void Main (string[] args) {
        string S = "aaabb";
 
        // Declare arrays to store the frequency of characters and
        // pairs of characters
        long[] arr1 = new long[26];
        long[,] arr2 = new long[26, 26];
 
        // Iterate over the string
        for (int i = 0; i < S.Length; i++) {
 
            // Convert the current character to its
            // corresponding index (0-25)
            int c = S[i] - 'a';
 
            // For each character, add its frequency to the
            // count of pairs with the current character
            for (int j = 0; j < 26; j++)
                arr2[j, c] += arr1[j];
 
            // Increment the frequency of the current character
            arr1++;
        }
 
        // Initialize the maximum frequency to 0
        long ans = 0;
 
        // Find the maximum frequency among all characters
        for (int i = 0; i < 26; i++)
            ans = Math.Max(ans, arr1[i]);
 
        // Find the maximum frequency among all pairs of
        // characters
        for (int i = 0; i < 26; i++)
            for (int j = 0; j < 26; j++)
                ans = Math.Max(ans, arr2[i, j]);
 
        Console.WriteLine(ans); // Print the maximum frequency
    }
}




function findMaxFrequency(S) {
    // Declare arrays to store the frequency of characters and pairs of characters
    const arr1 = new Array(26).fill(0);
    const arr2 = new Array(26).fill(null).map(() => new Array(26).fill(0));
 
    // Iterate over the string
    for (let i = 0; i < S.length; i++) {
        // Convert the current character to its corresponding index (0-25)
        const c = S.charCodeAt(i) - 'a'.charCodeAt(0);
 
        // For each character, add its frequency to the count of pairs with the current character
        for (let j = 0; j < 26; j++) {
            arr2[j] += arr1[j];
        }
 
        // Increment the frequency of the current character
        arr1++;
    }
 
    // Initialize the maximum frequency to 0
    let ans = 0;
 
    // Find the maximum frequency among all characters
    for (let i = 0; i < 26; i++) {
        ans = Math.max(ans, arr1[i]);
    }
 
    // Find the maximum frequency among all pairs of characters
    for (let i = 0; i < 26; i++) {
        for (let j = 0; j < 26; j++) {
            ans = Math.max(ans, arr2[i][j]);
        }
    }
 
    return ans; // Return the maximum frequency
}
 
// Example usage
const S = "aaabb";
const result = findMaxFrequency(S);
console.log(result); // Print the maximum frequency

Output
6











Time Complexity: O(N), where N is the length of the input string S.
Auxiliary Space: O(1)


Article Tags :