Check if string S2 can be obtained by appending subsequences of string S1 - GeeksforGeeks

16 Sep, 2021
Given two strings S1 and S2, the task is to check if it’s possible to generate string S2 by repeatedly appending subsequences of S1 to the end of an initially empty string. If possible, print “YES” and the minimum number of operations required. Otherwise, print “NO“.
Examples:
Input: S1 = “acebcd”, S2 = “acbcd” Output: YES 2 Explanation: Append subsequence “acbc” followed by “d” to obtain S2.
Input: S1 = “aceasd”, S2 = “asdxds” Output: NO Explanation: Since character ‘x’ is not present in S1, S2 cannot be obtained.
Approach: Follow the steps below to solve the problem:
Iterate over characters of string S1 and store frequencies of each character in S1 in an array freq[].
Traverse the string S2 and check if there is any character in S2 which is not present in S1. If any such character is found, print “NO”.
Otherwise, iterate over characters in S1 and update indices of each character in a Set
Traverse string S2 and for each character, check if it can be included in the current subsequence of S1 that can be appended.
If found to be true, set the index of current character as that of the last character appended. Otherwise, increase count of subsequences and set the index of current character as that of the last character appended. Proceed to the next character.
finally, print “YES” and the count of such subsequences as the required answer.
Below is the implementation of the above approach:
C++
Python3
// C++ Program to implement// the above approach#include "bits/stdc++.h"using namespace std; // Function for finding minimum// number of operationsint findMinimumOperations(string s,                          string s1){     // Stores the length of strings    int n = s.length(), m = s1.length();     // Stores frequency of    // characters in string s    int frequency[26] = { 0 };     // Update  frequencies of    // character in s    for (int i = 0; i < n; i++)        frequency[s[i] - 'a']++;     // Traverse string s1    for (int i = 0; i < m; i++) {         // If any character in s1        // is not present in s        if (frequency[s1[i] - 'a']            == 0) {            return -1;        }    }     // Stores the indices of    // each character in s    set<int> indices[26];     // Traverse string s    for (int i = 0; i < n; i++) {         // Store indices of characters        indices[s[i] - 'a'].insert(i);    }     int ans = 1;     // Stores index of last    // appended character    int last = (*indices[s1[0]                      - 'a']                     .begin());     // Traverse string s1    for (int i = 1; i < m; i++) {         int ch = s1[i] - 'a';         // Find the index of next        // character that can be appended        auto it = indices[ch].upper_bound(            last);         // Check if the current        // character be included        // in the current subsequence        if (it != indices[ch].end()) {            last = (*it);        }         // Otherwise        else {             // Start a new subsequence            ans++;             // Update index of last            // character appended            last = (*indices[ch].begin());        }    }    return ans;} // Driver Codeint main(){     string S1 = "acebcd", S2 = "acbcde";    int ans = findMinimumOperations(        S1, S2);     // If S2 cannot be obtained    // from subsequences of S1    if (ans == -1) {        cout << "NO\n";    }    // Otherwise    else {        cout << "YES\n"             << ans;    }     return 0;}
# Python3 Program to implement# the above approachfrom bisect import bisect ,bisect_left,bisect_right # Function for finding minimum# number of operationsdef findMinimumOperations(s,s1):     #Stores the length of strings    n = len(s)    m = len(s1)     # Stores frequency of    # characters in string s    frequency = [0]*26     # Update  frequencies of    # character in s    for i in range(n):        frequency[ord(s[i]) - ord('a')] += 1     # Traverse string s1    for i in range(m):         # If any character in s1        # is not present in s        if (frequency[ord(s1[i]) - ord('a')] == 0):            return -1     # Stores the indices of    # each character in s    indices = [[] for i in range(26)]     # Traverse string s    for i in range(n):         # Store indices of characters        indices[ord(s[i]) - ord('a')].append(i)     ans = 2     # Stores index of last    # appended character    last =len(indices[ord(s1[0])- ord('a')]) - 1     # Traverse string s1    for i in range(1,m):         ch = ord(s1[i]) - ord('a')         # Find the index of next        # character that can be appended        it = bisect_right(indices[ch],last)        # print(it)         # Check if the current        # character be included        # in the current subsequence        if (it != len(indices[ch])):            last = it        # Otherwise        else:             # Start a new subsequence            ans += 1             # Update index of last            # character appended            last = len(indices[ch])    return ans # Driver Codeif __name__ == '__main__':     S1 = "acebcd"    S2 = "acbcde"    ans = findMinimumOperations(S1, S2)     # If S2 cannot be obtained    # from subsequences of S1    if (ans == -1):        print("NO")    # Otherwise    else:        print("YES")        print(ans) # This code is contributed by mohit kumar 29
YES
2
 
Time Complexity: O(Mlog(N))Auxiliary Space: O(N)
reapedjuggler
mohit kumar 29
surindertarika1234
surinderdawra388
cpp-set
frequency-counting
subsequence
Greedy
Hash
Searching
Strings
Searching
Hash
Strings
Greedy
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Activity Selection Problem | Greedy Algo-1
Fractional Knapsack Problem
Program for Shortest Job First (or SJF) CPU Scheduling | Set 1 (Non- preemptive)
Job Sequencing Problem
Dijkstra’s Algorithm for Adjacency List Representation | Greedy Algo-8
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Internal Working of HashMap in Java
Hashing | Set 1 (Introduction)
Count pairs with given sum
Hashing | Set 3 (Open Addressing)