Maximize count of occurrences of S2 in S1 as a subsequence by concatenating N1 and N2 times respectively
Last Updated :
10 Jan, 2023
Given two strings S1, S2 of length N and M respectively, and two positive integers N1 and N2, the task is to find the maximum count of non-overlapping subsequences of S1 which are equal to S2 by concatenating the string s1, n1 times and the string s2, n2 times.
Examples:
Input: S1 = "acb", S2 = "ab", N1 = 4, N2 = 2
Output: 2
Explanation:
Concatenating the string S1, N1 ( = 4) times modifies S1 to "acbacbacbacb".
Concatenating the string S2, N2 ( = 2) times modifies S2 to "abab".
Since the string S2 occurs twice as a non-overlapping subsequence in S1, the required output is 2.
Input: S1 = "abc", S2 = "a", N1 = 1, N2 = 1
Output: 1
Approach: The problem can be solved using the concept of checking if a string is a subsequence of another string or not.
Follow the steps below to solve the problem:
- Iterate over the characters of the string S2 and check if all the characters of S2 are present in the string S1 or not. If found to be false, then no such subsequence of S1 is possible which can be made equal to S2 by concatenating the string S1, N1 times and the string S2, N2 times.
- Iterate over the characters of the string S1, N1 times circularly. For every ith index, check if any subsequence of S1 exists up to ith index, which is equal to S2 or not. If found to be true, then increment the count.
- Finally, print the count obtained divided by N2 as the required answer, after performing the above operations.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to count maximum number of
// occurrences of s2 as subsequence in s1
// by concatenating s1, n1 times and s2, n2 times
int getMaxRepetitions(string s1, int n1,
string s2, int n2)
{
int temp1[26] = {0}, temp2[26] = {0};
for(char i:s1) temp1[i - 'a']++;
for(char i:s2) temp2[i - 'a']++;
for(int i = 0; i < 26; i++)
{
if(temp2[i] > temp1[i]) return 0;
}
// Stores number of times
// s1 is traversed
int s1_reps = 0;
// Stores number of times
// s2 is traversed
int s2_reps = 0;
// Mapping index of s2 to number
// of times s1 and s2 are traversed
map<int, pair<int, int> > s2_index_to_reps;
s2_index_to_reps[0] = {0, 0};
// Stores index of s1 circularly
int i = 0;
// Stores index of s2 circularly
int j = 0;
// Traverse the string s1, n1 times
while (s1_reps < n1){
// If current character of both
// the string are equal
if (s1[i] == s2[j])
// Update j
j += 1;
// Update i
i += 1;
// If j is length of s2
if (j == s2.size())
{
// Update j for
// circular traversal
j = 0;
// Update s2_reps
s2_reps += 1;
}
// If i is length of s1
if (i == s1.size())
{
// Update i for
// circular traversal
i = 0;
// Update s1_reps
s1_reps += 1;
// If already mapped j
// to (s1_reps, s2_reps)
if (s2_index_to_reps.find(j) !=
s2_index_to_reps.end())
break;
// Mapping j to (s1_reps, s2_reps)
s2_index_to_reps[j] = {s1_reps, s2_reps};
}
}
// If s1 already traversed n1 times
if (s1_reps == n1)
return s2_reps / n2;
// Otherwise, traverse string s1 by multiple of
// s1_reps and update both s1_reps and s2_reps
int initial_s1_reps = s2_index_to_reps[j].first ,
initial_s2_reps = s2_index_to_reps[j].second;
int loop_s1_reps = s1_reps - initial_s1_reps;
int loop_s2_reps = s2_reps - initial_s2_reps;
int loops = (n1 - initial_s1_reps);
// Update s2_reps
s2_reps = initial_s2_reps + loops * loop_s2_reps;
// Update s1_reps
s1_reps = initial_s1_reps + loops * loop_s1_reps;
// If s1 is traversed less than n1 times
while (s1_reps < n1)
{
// If current character in both
// the string are equal
if (s1[i] == s2[j])
// Update j
j += 1;
// Update i
i += 1;
// If i is length of s1
if (i == s1.size())
{
// Update i for circular traversal
i = 0;
// Update s1_reps
s1_reps += 1;
}
// If j is length of ss
if (j == s2.size())
{
// Update j for circular traversal
j = 0;
// Update s2_reps
s2_reps += 1;
}
}
return s2_reps / n2;
}
// Driver Code
int main()
{
string s1 = "acb";
int n1 = 4;
string s2 = "ab";
int n2 = 2;
cout << (getMaxRepetitions(s1, n1, s2, n2));
return 0;
}
// This code is contributed by mohit kumar 29.
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Function to count maximum number of
// occurrences of s2 as subsequence in s1
// by concatenating s1, n1 times and s2, n2 times
static int getMaxRepetitions(String s1, int n1,
String s2, int n2)
{
int temp1[] = new int[26], temp2[] = new int[26];
for(char i : s1.toCharArray())
temp1[i - 'a']++;
for(char i : s2.toCharArray())
temp2[i - 'a']++;
for(int i = 0; i < 26; i++)
{
if (temp2[i] > temp1[i])
return 0;
}
// Stores number of times
// s1 is traversed
int s1_reps = 0;
// Stores number of times
// s2 is traversed
int s2_reps = 0;
// Mapping index of s2 to number
// of times s1 and s2 are traversed
HashMap<Integer, int[]> s2_index_to_reps = new HashMap<>();
s2_index_to_reps.put(0, new int[] { 0, 0 });
// Stores index of s1 circularly
int i = 0;
// Stores index of s2 circularly
int j = 0;
// Traverse the string s1, n1 times
while (s1_reps < n1)
{
// If current character of both
// the string are equal
if (s1.charAt(i) == s2.charAt(j))
// Update j
j += 1;
// Update i
i += 1;
// If j is length of s2
if (j == s2.length())
{
// Update j for
// circular traversal
j = 0;
// Update s2_reps
s2_reps += 1;
}
// If i is length of s1
if (i == s1.length())
{
// Update i for
// circular traversal
i = 0;
// Update s1_reps
s1_reps += 1;
// If already mapped j
// to (s1_reps, s2_reps)
if (!s2_index_to_reps.containsKey(j))
break;
// Mapping j to (s1_reps, s2_reps)
s2_index_to_reps.put(
j, new int[] { s1_reps, s2_reps });
}
}
// If s1 already traversed n1 times
if (s1_reps == n1)
return s2_reps / n2;
// Otherwise, traverse string s1 by multiple of
// s1_reps and update both s1_reps and s2_reps
int initial_s1_reps = s2_index_to_reps.get(j)[0],
initial_s2_reps = s2_index_to_reps.get(j)[1];
int loop_s1_reps = s1_reps - initial_s1_reps;
int loop_s2_reps = s2_reps - initial_s2_reps;
int loops = (n1 - initial_s1_reps);
// Update s2_reps
s2_reps = initial_s2_reps + loops * loop_s2_reps;
// Update s1_reps
s1_reps = initial_s1_reps + loops * loop_s1_reps;
// If s1 is traversed less than n1 times
while (s1_reps < n1)
{
// If current character in both
// the string are equal
if (s1.charAt(i) == s2.charAt(j))
// Update j
j += 1;
// Update i
i += 1;
// If i is length of s1
if (i == s1.length())
{
// Update i for circular traversal
i = 0;
// Update s1_reps
s1_reps += 1;
}
// If j is length of ss
if (j == s2.length())
{
// Update j for circular traversal
j = 0;
// Update s2_reps
s2_reps += 1;
}
}
return s2_reps / n2;
}
// Driver Code
public static void main(String[] args)
{
String s1 = "acb";
int n1 = 4;
String s2 = "ab";
int n2 = 2;
System.out.println(
getMaxRepetitions(s1, n1, s2, n2));
}
}
// This code is contributed by Kingash
Python3
# Python3 program for the above approach
# Function to count maximum number of
# occurrences of s2 as subsequence in s1
# by concatenating s1, n1 times and s2, n2 times
def getMaxRepetitions(s1, n1, s2, n2):
# If all the characters of s2 are not present in s1
if any(c for c in set(s2) if c not in set(s1)):
return 0
# Stores number of times
# s1 is traversed
s1_reps = 0
# Stores number of times
# s2 is traversed
s2_reps = 0
# Mapping index of s2 to number
# of times s1 and s2 are traversed
s2_index_to_reps = { 0 : (0, 0)}
# Stores index of s1 circularly
i = 0
# Stores index of s2 circularly
j = 0
# Traverse the string s1, n1 times
while s1_reps < n1:
# If current character of both
# the string are equal
if s1[i] == s2[j]:
# Update j
j += 1
# Update i
i += 1
# If j is length of s2
if j == len(s2):
# Update j for
# circular traversal
j = 0
# Update s2_reps
s2_reps += 1
# If i is length of s1
if i == len(s1):
# Update i for
# circular traversal
i = 0
# Update s1_reps
s1_reps += 1
# If already mapped j
# to (s1_reps, s2_reps)
if j in s2_index_to_reps:
break
# Mapping j to (s1_reps, s2_reps)
s2_index_to_reps[j] = (s1_reps, s2_reps)
# If s1 already traversed n1 times
if s1_reps == n1:
return s2_reps // n2
# Otherwise, traverse string s1 by multiple of
# s1_reps and update both s1_reps and s2_reps
initial_s1_reps, initial_s2_reps = s2_index_to_reps[j]
loop_s1_reps = s1_reps - initial_s1_reps
loop_s2_reps = s2_reps - initial_s2_reps
loops = (n1 - initial_s1_reps)
# Update s2_reps
s2_reps = initial_s2_reps + loops * loop_s2_reps
# Update s1_reps
s1_reps = initial_s1_reps + loops * loop_s1_reps
# If s1 is traversed less than n1 times
while s1_reps < n1:
# If current character in both
# the string are equal
if s1[i] == s2[j]:
# Update j
j += 1
# Update i
i += 1
# If i is length of s1
if i == len(s1):
# Update i for circular traversal
i = 0
# Update s1_reps
s1_reps += 1
# If j is length of ss
if j == len(s2):
# Update j for circular traversal
j = 0
# Update s2_reps
s2_reps += 1
return s2_reps // n2
# Driver Code
if __name__ == '__main__':
s1 = "acb"
n1 = 4
s2 = "ab"
n2 = 2
print(getMaxRepetitions(s1, n1, s2, n2))
JavaScript
<script>
// Javascript program for the above approach
// Function to count maximum number of
// occurrences of s2 as subsequence in s1
// by concatenating s1, n1 times and s2, n2 times
function getMaxRepetitions(s1,n1,s2,n2)
{
let temp1 = new Array(26);
let temp2 = new Array(26);
for(let i = 0; i < 26; i++)
{
temp1[i] = 0;
temp2[i] = 0;
}
for(let i = 0; i < s1.split("").length; i++)
temp1[s1[i].charCodeAt(0) - 'a'.charCodeAt(0)]++;
for(let i = 0; i < s2.split("").length; i++)
temp2[s2[i].charCodeAt(0) - 'a'.charCodeAt(0)]++;
for(let i = 0; i < 26; i++)
{
if (temp2[i] > temp1[i])
return 0;
}
// Stores number of times
// s1 is traversed
let s1_reps = 0;
// Stores number of times
// s2 is traversed
let s2_reps = 0;
// Mapping index of s2 to number
// of times s1 and s2 are traversed
let s2_index_to_reps = new Map();
s2_index_to_reps.set(0, [ 0, 0 ]);
// Stores index of s1 circularly
let i = 0;
// Stores index of s2 circularly
let j = 0;
// Traverse the string s1, n1 times
while (s1_reps < n1)
{
// If current character of both
// the string are equal
if (s1[i] == s2[j])
// Update j
j += 1;
// Update i
i += 1;
// If j is length of s2
if (j == s2.length)
{
// Update j for
// circular traversal
j = 0;
// Update s2_reps
s2_reps += 1;
}
// If i is length of s1
if (i == s1.length)
{
// Update i for
// circular traversal
i = 0;
// Update s1_reps
s1_reps += 1;
// If already mapped j
// to (s1_reps, s2_reps)
if (!s2_index_to_reps.has(j))
break;
// Mapping j to (s1_reps, s2_reps)
s2_index_to_reps.set(
j, [s1_reps, s2_reps ]);
}
}
// If s1 already traversed n1 times
if (s1_reps == n1)
return s2_reps / n2;
// Otherwise, traverse string s1 by multiple of
// s1_reps and update both s1_reps and s2_reps
let initial_s1_reps = s2_index_to_reps.get(j)[0],
initial_s2_reps = s2_index_to_reps.get(j)[1];
let loop_s1_reps = s1_reps - initial_s1_reps;
let loop_s2_reps = s2_reps - initial_s2_reps;
let loops = (n1 - initial_s1_reps);
// Update s2_reps
s2_reps = initial_s2_reps + loops * loop_s2_reps;
// Update s1_reps
s1_reps = initial_s1_reps + loops * loop_s1_reps;
// If s1 is traversed less than n1 times
while (s1_reps < n1)
{
// If current character in both
// the string are equal
if (s1[i] == s2[j])
// Update j
j += 1;
// Update i
i += 1;
// If i is length of s1
if (i == s1.length)
{
// Update i for circular traversal
i = 0;
// Update s1_reps
s1_reps += 1;
}
// If j is length of ss
if (j == s2.length)
{
// Update j for circular traversal
j = 0;
// Update s2_reps
s2_reps += 1;
}
}
return s2_reps / n2;
}
// Driver Code
let s1 = "acb";
let n1 = 4;
let s2 = "ab";
let n2 = 2;
document.write(getMaxRepetitions(s1, n1, s2, n2));
// This code is contributed by unknown2108
</script>
C#
using System;
using System.Collections.Generic;
class GFG
{
// Function to count maximum number of
// occurrences of s2 as subsequence in s1
// by concatenating s1, n1 times and s2, n2 times
static int GetMaxRepetitions(string s1, int n1,
string s2, int n2)
{
int[] temp1 = new int[26], temp2 = new int[26];
foreach (char x in s1)
temp1[x - 'a']++;
foreach (char x in s2)
temp2[x - 'a']++;
for (int k = 0; k < 26; k++)
{
if (temp2[k] > temp1[k])
return 0;
}
// Stores number of times
// s1 is traversed
int s1Reps = 0;
// Stores number of times
// s2 is traversed
int s2Reps = 0;
// Mapping index of s2 to number
// of times s1 and s2 are traversed
Dictionary<int, int[]> s2IndexToReps = new Dictionary<int, int[]>();
s2IndexToReps[0] = new int[] { 0, 0 };
// Stores index of s1 circularly
int i = 0;
// Stores index of s2 circularly
int j = 0;
// Traverse the string s1, n1 times
while (s1Reps < n1)
{
// If current character of both
// the string are equal
if (s1[i] == s2[j])
// Update j
j += 1;
// Update i
i += 1;
// If j is length of s2
if (j == s2.Length)
{
// Update j for
// circular traversal
j = 0;
// Update s2Reps
s2Reps += 1;
}
// If i is length of s1
if (i == s1.Length)
{
// Update i for
// circular traversal
i = 0;
// Update s1Reps
s1Reps += 1;
// If already mapped j
// to (s1Reps, s2Reps)
if (!s2IndexToReps.ContainsKey(j))
break;
// Mapping j to (s1Reps, s2Reps)
s2IndexToReps[j] = new int[] { s1Reps, s2Reps };
}
}
// If s1 already traversed n1 times
if (s1Reps == n1)
return s2Reps / n2;
// Otherwise, traverse string s1 by multiple of
// s1Reps and update both s1Reps and s2Reps
int initialS1Reps = s2IndexToReps[j][0],
initialS2Reps = s2IndexToReps[j][1];
int loop_s1Reps = s1Reps - initialS1Reps;
int loop_s2Reps = s2Reps - initialS2Reps;
int loops = (n1 - initialS1Reps);
// Update s2Reps
s2Reps = initialS2Reps + loops * loop_s2Reps;
// Update s1Reps
s1Reps = initialS1Reps + loops * loop_s1Reps;
// If s1 is traversed less than n1 times
while (s1Reps < n1)
{
// If current character in both
// the string are equal
if (s1[j] == s2[j])
// Update j
j += 1;
// Update i
i += 1;
// If i is length of s1
if (i == s1.Length)
{
// Update i for circular traversal
i = 0;
// Update s1Reps
s1Reps += 1;
}
// If j is length of ss
if (j == s2.Length)
{
// Update j for circular traversal
j = 0;
// Update s2Reps
s2Reps += 1;
}
}
return s2Reps / n2;
}
// Driver Code
public static void Main(string[] args)
{
string s1 = "acb";
int n1 = 4;
string s2 = "ab";
int n2 = 2;
Console.WriteLine(
GetMaxRepetitions(s1, n1, s2, n2));
}
}
Time Complexity: O((N + M) * n1)
Auxiliary Space:O(1)
Similar Reads
Concatenate the strings in an order which maximises the occurrence of subsequence "ab" Given N strings containing of characters 'a' and 'b'. These string can be concatenated in any order to make a single final string S. The score of the final string S is defined as the number of occurrences of the subsequence "ab" in it. Now, the task is to concatenate the string in such a way that th
12 min read
Count subsequences 01 in string generated by concatenation of given numeric string K times Given a string S and a positive integer K, the task is to find the number of subsequences "01" in the string generated by concatenation of the given numeric string S K times. Examples: Input: S = "0171", K = 2Output: 6Explanation:The string formed by concatenation of S, K number of times is "0171017
6 min read
Maximum number of times a given string needs to be concatenated to form a substring of another string Given two strings S1 and S2 of length N and M respectively, the task is to find the maximum value of times the string S2 needs to be concatenated, such that it is a substring of the string S1. Examples: Input: S1 = "ababc", S2 = "ab"Output: 2Explanation: After concatenating S2 exactly twice, the str
12 min read
Minimize the number of strictly increasing subsequences in an array | Set 2 Given an array arr[] of size N, the task is to print the minimum possible count of strictly increasing subsequences present in the array. Note: It is possible to swap the pairs of array elements. Examples: Input: arr[] = {2, 1, 2, 1, 4, 3}Output: 2Explanation: Sorting the array modifies the array to
6 min read
Count maximum occurrence of subsequence in string such that indices in subsequence is in A.P. Given a string S, the task is to count the maximum occurrence of subsequences in the given string such that the indices of the characters of the subsequence are Arithmetic Progression. Examples: Input: S = "xxxyy" Output: 6 Explanation: There is a subsequence "xy", where indices of each character of
12 min read
Longest increasing sub-sequence formed by concatenating array to itself N times Given an array arr[] of size N, the task is to find the length of the longest increasing subsequence in the array formed by the concatenation of the arr[] to itself at the end N times.Examples: Input: arr[] = {3, 2, 1}, N = 3 Output: 3 Explanation: The array formed by the concatenation - {3, 2, 1, 3
5 min read
Maximize the function by choosing Subsequence of size M Given an array A[] with size N, Select a subsequence B = {B[1], B[2], B[3], .........B[N] } of size M from given array A[] (N ? M), the task is to find the maximum value of ? i * B[i] where i is from 1 to M. The sequence of a given sequence is a sequence that can be derived from the given sequence b
15 min read
Subsequence pair from given Array having all unique and all same elements respectively Given an array arr[] of N integers, the task is to choose the two subsequences of equal lengths such that the first subsequence must have all the unique elements and the second subsequence must have all the same elements. Print the maximum length of the subsequence pair. Examples: Input: arr[] = {1,
6 min read
Number of subsequences as "ab" in a string repeated K times Given a String S, consider a new string formed by repeating the S exactly K times. We need find the number of subsequences as âabâ in the newly formed string. Examples : Input : S = "abcb" K = 2 Output : 6 Here, Given string is repeated 2 times and we get a new string "abcbabcb" Below are 6 occurren
10 min read
Count of maximum occurring subsequence using only those characters whose indices are in GP Given a string S, the task is to find the count of maximum occurring subsequence P from S using only those characters whose indexes are in Geometric Progression.Note: Consider 1-based indexing in S. Examples : Input: S = "ddee"Output: 4Explanation: If we take P = "de", then P occurs 4 times in S. {
7 min read