Open In App

Check if given String can be split only into subsequences ABC

Improve
Improve
Like Article
Like
Save
Share
Report

Given a string S of length N where each character of the string is either ‘A‘, ‘B‘ or ‘C‘. The task is to find if is it possible to split the string into subsequences “ABC“. If it is possible to split then print “Yes“. Otherwise, print “No“.

Examples:

Input: S = “ABABCC”
Output: Yes
Explanation:
One of the possible way of splitting is to split the string in 2 subsequences of “ABC” is following:

  • First form a subsequence “ABC” by taking the character at indices 0, 1, and 4.
  • Again form a subsequence “ABC” by taking the character at indices 2, 3, and 5.

Therefore, the string can be split in 2 subsequences of “ABC”.

Input: S = “AABBCC”
Output: Yes
Explanation:
One of the possible way of splitting is to split the string in 2 subsequences of “ABC” is following:

  • First form a subsequence “ABC” by taking the character at indices 0, 2, and 4
  • Again form a subsequence “ABC” by taking the character at indices 1, 3, and 5.

Therefore, the string can be split in 2 subsequences of “ABC”.

Input: S = “BAC”
Output: No

Approach: The given problem can be solved based on the following observations: 

  • It can be observed that if N is not multiple of 3 or count of ‘A‘, ‘B‘, and ‘C‘ are not equal then it will be impossible to split the string satisfying the conditions.
  • Also, for every ‘B‘ there must be at least one ‘A‘ to its left and one ‘C’ to its right.

Follow the steps below to solve the problem:

  • Initialize 3 deques of integers say A, B, and C to store the indices of characters ‘A‘, ‘B‘ and ‘C‘ respectively.
  • Iterate over characters of the string S and in each iteration, if the current character is ‘A‘ then push the index i into A. Else if the current character is ‘B‘ then push the index i into B. Otherwise, push the index i into C.
  • If N is not multiple of 3 and count of characters ‘A‘, ‘B‘ and ‘C‘ are not equal then print “No”.
  • Otherwise, Iterate over the deque B using the variable i, and in each iteration, if B[i] is greater than the front element of deque A then Pop the front element of deque A. Otherwise print “No” and return.
  • Now again iterate over the deque B using the variable i in reverse and in each iteration if B[i] is lesser than the last element of deque C then Pop the last element of the deque C. Otherwise print “No” and return.
  • Finally, if none of the above cases satisfy then print “Yes” as the answer.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if the given
// string can be splitted into
// subsequences "ABC"
string check(string S)
{
    // Stores the length
    // of the string
    int N = S.length();
 
    // Stores the indices of 'A'
    deque<int> A;
    // Stores the indices of 'B'
    deque<int> B;
    // Stores the indices of 'C'
    deque<int> C;
 
    // Traverse the string S
    for (int i = 0; i < N; i++) {
 
        // If S[i] is equal to 'A'
        if (S[i] == 'A') {
            // Push the index i in A
            A.push_back(i);
        }
        // Else if S[i] is equal
        // to 'B'
        else if (S[i] == 'B') {
            // Push the index i in B
            B.push_back(i);
        }
 
        // Else if S[i] is equal
        // to 'C'
        else {
            // Push the index i in C
            C.push_back(i);
        }
    }
 
    // If N is not multiple of 3 or
    // count of characters 'A', 'B'
    // and 'C' are not equal
    if (N % 3 || A.size() != B.size()
        || A.size() != C.size()) {
 
        // Return "No"
        return "No";
    }
    // Iterate over the deque B
    for (int i = 0; i < B.size(); i++) {
 
        // If A is not empty and
        // B[i] is greater than
        // A[0]
        if (!A.empty() && B[i] > A[0]) {
            // Removes the front
            // element of A
            A.pop_front();
        }
        // Else return "No"
        else {
            return "No";
        }
    }
    // Iterate over the deque
    // B in reverse
    for (int i = B.size() - 1; i >= 0; i--) {
        // If C is not empty and
        // last element of C is
        // greater thab B[i]
        if (!C.empty() && B[i] < C.back()) {
            // Removes the last
            // element of C
            C.pop_back();
        }
        // Else return "No"
        else {
            return "No";
        }
    }
 
    // If none of the above
    // cases satisfy return
    //"Yes'
    return "Yes";
}
 
// Driver Code
int main()
{
    // Input
    string S = "ABABCC";
 
    // Function call
    cout << check(S) << endl;
    return 0;
}


Java




// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG{
     
// Function to check if the given
// string can be splitted into
// subsequences "ABC"
public static String check(String S)
{
     
    // Stores the length
    // of the string
    int N = S.length();
 
    // Stores the indices of 'A'
    Deque<Integer> A = new LinkedList<Integer>();
     
    // Stores the indices of 'B'
    Deque<Integer> B = new LinkedList<Integer>();
     
    // Stores the indices of 'C'
    Deque<Integer> C = new LinkedList<Integer>();
     
    // Traverse the string S
    for(int i = 0; i < N; i++)
    {
         
        // If S[i] is equal to 'A'
        if (S.charAt(i) == 'A')
        {
             
            // Push the index i in A
            A.addLast(i);
        }
         
        // Else if S[i] is equal
        // to 'B'
        else if (S.charAt(i) == 'B')
        {
             
            // Push the index i in B
            B.addLast(i);
        }
         
        // Else if S[i] is equal
        // to 'C'
        else
        {
             
            // Push the index i in C
            C.addLast(i);
        }
    }
 
    // If N is not multiple of 3 or
    // count of characters 'A', 'B'
    // and 'C' are not equal
    if (N % 3 > 0 || A.size() != B.size() ||
        A.size() != C.size())
    {
         
        // Return "No"
        return "No";
    }
     
    // Iterate over the deque B
    for(Iterator itr = B.iterator(); itr.hasNext();)
    {
        Integer b = (Integer)itr.next();
         
        // If A is not empty and
        // curr B is greater than
        // A[0]
        if (A.size() > 0 && b > A.getFirst())
        {
             
            // Removes the front
            // element of A
            A.pop();
        }
         
        // Else return "No"
        else
        {
            return "No";
        }
    }
 
    // Iterate over the deque
    // B in reverse
    for(Iterator itr = B.descendingIterator();
        itr.hasNext();)
    {
        Integer b = (Integer)itr.next();
         
        // If C is not empty and
        // last element of C is
        // greater thab B[i]
        if (C.size() > 0 && b < C.getLast())
        {
             
            // Removes the last
            // element of C
            C.pollLast();
        }
         
        // Else return "No"
        else
        {
            return "No";
        }
    }
     
    // If none of the above
    // cases satisfy return
    //"Yes'
    return "Yes";
}
 
// Driver code
public static void main(String[] args)
{
     
    // Input
    String S = "ABABCC";
 
    // Function call
    System.out.println(check(S));
}
}
 
// This code is contributed by Manu Pathria


Python3




# Python3 program for the above approach
from collections import deque
 
# Function to check if the given
# can be splitted into
# subsequences "ABC"
def check(S):
     
    # Stores the length
    # of the string
    N = len(S)
 
    # Stores the indices of 'A'
    A = deque()
     
    # Stores the indices of 'B'
    B = deque()
     
    # Stores the indices of 'C'
    C = deque()
 
    # Traverse the S
    for i in range(N):
         
        # If S[i] is equal to 'A'
        if (S[i] == 'A'):
             
            # Push the index i in A
            A.append(i)
             
        # Else if S[i] is equal
        # to 'B'
        elif (S[i] == 'B'):
             
            # Push the index i in B
            B.append(i)
             
        # Else if S[i] is equal
        # to 'C'
        else:
             
            # Push the index i in C
            C.append(i)
 
    # If N is not multiple of 3 or
    # count of characters 'A', 'B'
    # and 'C' are not equal
    if (N % 3 or len(A) != len(B) or
                 len(A) != len(C)):
                      
        # Return "No"
        return "No"
         
    # Iterate over the deque B
    for i in range(len(B)):
         
        # If A is not empty and
        # B[i] is greater than
        # A[0]
        if (len(A) > 0 and B[i] > A[0]):
             
            # Removes the front
            # element of A
            A.popleft()
             
        # Else return "No"
        else:
            return "No"
 
    # Iterate over the deque
    # B in reverse
    for i in range(len(B) - 1, -1, -1):
         
        # If C is not empty and
        # last element of C is
        # greater thab B[i]
        if (len(C) > 0 and B[i] < C[-1]):
             
            # Removes the last
            # element of C
            C.popleft()
             
        # Else return "No"
        else:
            return "No"
 
    # If none of the above
    # cases satisfy return
    # "Yes'
    return "Yes"
 
# Driver Code
if __name__ == '__main__':
     
    # Input
    S = "ABABCC"
 
    # Function call
    print(check(S))
 
# This code is contributed by mohit kumar 29


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public static class GFG {
     
    public static IEnumerable<T> Reverse<T>(this LinkedList<T> list) {
        var el = list.Last;
        while (el != null) {
            yield return el.Value;
            el = el.Previous;
        }
    }
     
    // Function to check if the given
    // string can be splitted into
    // subsequences "ABC"
    public static string check(string S)
    {
         
        // Stores the length
        // of the string
        int N = S.Length;
     
        // Stores the indices of 'A'
        LinkedList<int> A = new LinkedList<int>();
         
        // Stores the indices of 'B'
        LinkedList<int> B = new LinkedList<int>();
         
        // Stores the indices of 'C'
        LinkedList<int> C = new LinkedList<int>();
         
        // Traverse the string S
        for(int i = 0; i < N; i++)
        {
             
            // If S[i] is equal to 'A'
            if (S[i] == 'A')
            {
                 
                // Push the index i in A
                A.AddLast(i);
            }
             
            // Else if S[i] is equal
            // to 'B'
            else if (S[i] == 'B')
            {
                 
                // Push the index i in B
                B.AddLast(i);
            }
             
            // Else if S[i] is equal
            // to 'C'
            else
            {
                 
                // Push the index i in C
                C.AddLast(i);
            }
        }
     
        // If N is not multiple of 3 or
        // count of characters 'A', 'B'
        // and 'C' are not equal
        if (N % 3 > 0 || A.Count != B.Count ||
            A.Count != C.Count)
        {
             
            // Return "No"
            return "No";
        }
         
        // Iterate over the deque B
        foreach(var itr in B)
        {
            int b = itr;
             
            // If A is not empty and
            // curr B is greater than
            // A[0]
            if (A.Count > 0 && b > A.First.Value)
            {
                 
                // Removes the front
                // element of A
                A.RemoveFirst();
            }
             
            // Else return "No"
            else
            {
                return "No";
            }
        }
     
        // Iterate over the deque
        // B in reverse
        foreach(var itr in B.Reverse())
        {
            int b = itr;
             
            // If C is not empty and
            // last element of C is
            // greater thab B[i]
            if (C.Count > 0 && b < C.Last.Value)
            {
                 
                // Removes the last
                // element of C
                C.RemoveLast();
            }
             
            // Else return "No"
            else
            {
                return "No";
            }
        }
         
        // If none of the above
        // cases satisfy return
        //"Yes'
        return "Yes";
    }
     
    // Driver code
    static public void Main (){
         
        // Input
        string S = "ABABCC";
     
        // Function call
        Console.Write(check(S));
    }
}
 
// This Code is contributed by ShubhamSingh10


Javascript




// JavaScript program for the above approach
 
// Function to check if the given
// can be splitted into
// subsequences "ABC"
function check(S) {
    // Stores the length
    // of the string
    const N = S.length;
 
    // Stores the indices of 'A'
    const A = [];
 
    // Stores the indices of 'B'
    const B = [];
 
    // Stores the indices of 'C'
    const C = [];
 
    // Traverse the S
    for (let i = 0; i < N; i++) {
 
        // If S[i] is equal to 'A'
        if (S[i] === 'A') {
 
            // Push the index i in A
            A.push(i);
 
            // Else if S[i] is equal
            // to 'B'
        } else if (S[i] === 'B') {
 
            // Push the index i in B
            B.push(i);
 
            // Else if S[i] is equal
            // to 'C'
        } else {
 
            // Push the index i in C
            C.push(i);
        }
    }
 
    // If N is not multiple of 3 or
    // count of characters 'A', 'B'
    // and 'C' are not equal
    if (N % 3 || A.length !== B.length || A.length !== C.length) {
 
        // Return "No"
        return "No";
    }
 
    // Iterate over the deque B
    for (let i = 0; i < B.length; i++) {
 
        // If A is not empty and
        // B[i] is greater than
        // A[0]
        if (A.length > 0 && B[i] > A[0]) {
 
            // Removes the front
            // element of A
            A.shift();
 
            // Else return "No"
        } else {
            return "No";
        }
    }
 
    // Iterate over the deque
    // B in reverse
    for (let i = B.length - 1; i >= 0; i--) {
 
        // If C is not empty and
        // last element of C is
        // greater thab B[i]
        if (C.length > 0 && B[i] < C[C.length - 1]) {
 
            // Removes the last
            // element of C
            C.pop();
 
            // Else return "No"
        } else {
            return "No";
        }
    }
 
    // If none of the above
    // cases satisfy return
    // "Yes'
    return "Yes";
}
 
// Driver Code
const S = "ABABCC";
 
// Function call
console.log(check(S));
 
// Contributed by adityashae15


Output

Yes

Time Complexity: O(N)
Auxiliary Space: O(N)



Last Updated : 08 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads