Open In App

Check if subsequences formed by given characters are same for Q queries

Last Updated : 28 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of N strings, and Q queries where each of the queries contains some characters, the task is to check, for each query, if all strings contain the subsequence consisting of all occurrences of the characters in that query. 

A subsequence is a sequence that can be derived from the given sequence by deleting some or no elements without changing the order of the remaining elements. 

Examples:

Input: arr[] = {“accbad”, “abcacd”, “cacbda”}, queries[] = {{‘a’}, {‘a’, ‘b’}, {‘a’, ‘d’}, {‘b’, ‘c’, ‘d’}, {‘a’, ‘b’, ‘d’}
Output: 
True
True
False
True
False
False
Explanation: All strings generate the subsequence “aa” using only the character ‘a’.
All strings generate subsequence “aba” using only the characters ‘a’ and ‘b’.
arr[1] and arr[2] generate subsequence “aad”, but arr[3] generates subsequence “ada” using only the characters ‘a’ and ‘d’, and since subsequences don’t match, false is printed.
All strings generate the subsequence “bd” using only the characters ‘b’ and ‘d’
arr[1] and arr[3] generate subsequence “ccbd”, but arr[2] generates subsequence “bccd” using only the characters ‘b’, ‘c’, and ‘d’, so print ‘False’.
arr[1] and arr[2] generate subsequence “abad”, but arr[3] generates subsequence “abda” using only the characters ‘a’, ‘b’, and ‘d’

Input: arr[] = {“adacb”, “aacbd”}, queries[] = {{‘a’, ‘b’, ‘c’}}
Output: True.
Explanation: The subsequences are ‘aacb’ for both the strings

 

Naive Approach: For each query generate the subsequences containing all the occurrences of all the characters of that query and check if they are the same or not.

Time complexity: O(Q * N * M), where M is the average length of each string.
Auxiliary Space: O(1)

Efficient Approach using Memoization: This problem can be solved efficiently based on the following idea:

If the relative positions of all the characters for a query are the same in all the strings then the subsequence is common among all of them.

The relative positions of any character (say character ch), can be found out by finding the frequencies of all the characters of a query up to the index of ch. If they are the same then their relative positions are also same.

Follow the steps mentioned below to implement the idea:

  • Create a 3-dimensional (say elements[]) array to store the frequency of each character of the strings up to each index.
  • Traverse all the strings and find the frequency and store them.
  • Now check for the relative positions of the characters of a query.
  • To implement this efficiently, iterate through the array of strings, compare the adjacent strings and do the following:
    • Find the relative position of each character with respect to every other character in the English alphabet (relative position is checked by checking the frequencies of all other characters till that index).
    • If they are not the same for a character (say ch) in two strings, add the characters which are causing the mismatch in a set. (mismatch means frequency counts are not the same)
    • Check if the mismatches found are the same as the characters of the query.
    • If so then the subsequences formed are not the same. So return false.
  • After the iteration is over and a “false” is not returned, then subsequences formed are the same.

Follow the illustration below for a better understanding.

Illustration:

Say arr[] = {“adacb”, “aacbd”}, queries[] = {{‘a’, ‘b’, ‘c’}}

The frequencies of all the characters for arr[0] and arr[1] are shown below

arr[0] = 

 

‘a’

‘d’ ‘a’ ‘c’ ‘b’
a 1 1 2 2 2
b 0 0 0 0 1
c 0 0 0 1 1
d 0 1 1 1 1

arr[1] = 

 

‘a’

‘a’ ‘c’ ‘b’ ‘d’
a 1 2 2 2 2
b 0 0 0 1 1
c 0 0 1 1 1
d 0 0 0 0 1

For ‘a’:
        => The relative positions of the second ‘a’ are not same.
        => In the first string there is an extra ‘d’ before the 2nd ‘a’.
        => So the mismatch set is { ‘d’ }.

For ‘b’:
        => The relative positions of ‘b’ are not same.
        => In the first string there is an extra ‘d’ before it.
        => So the mismatch set is { ‘d’ }.

For ‘c’:
        => The relative positions of ‘c’ are not same.
        => In the first string there is an extra ‘d’ before it.
        => So the mismatch set is { ‘d’ }.

Now no mismatch set contains the same character as the ones present in the query. So the subsequence formed is the same for the strings.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if the subsequences formed are the same
vector<bool> isPossible(int N, vector<string>& arr, int Q,
                        string queries[])
{
  // For 26 letters
  const int numElements = 26;
 
  // Generate prefix sums (for each letter)
  // for each string
  vector<vector<vector<int> > > elements;
  for (int i = 0; i < N; i++)
  {
 
    // Create a new prefix sum array
    // and add it to the array list
    vector<vector<int> > tmp(
      arr[i].size(), vector<int>(numElements, 0));
 
    // Build the prefix sum
    // at each position in the string
    for (int j = 0; j < arr[i].size(); j++) {
      for (int k = 0; k < numElements; k++) {
        if (j != 0)
          tmp[j][k] = tmp[j - 1][k];
      }
      // ASCII to int conversion
      // for lowercase letters
      tmp[j][arr[i][j] - 'a']++;
    }
    elements.push_back(tmp);
  }
  // Generate the set of characters
  // which are necessary to remove.
  // Each mapping is the set
  // corresponding of characters
  // which need to be removed.
  // for each letter in order for a
  // subsequence to be generated.
  map<int, set<int> > requiredRemovals;
  for (int i = 0; i < numElements; i++)
    requiredRemovals[i] = {};
  // Iterate over all the characters
  // (in the alphabet in this case)
  for (int i = 0; i < numElements; i++) {
 
    // For each character,
    // go through all M strings
    // to generate prefix sums
    for (int j = 1; j < N; j++) {
      // String a stores
      // the previous string (j-1)
      // string b stores
      // the current string (j)
      string a = arr[j - 1];
      string b = arr[j];
 
      // Store the prefix sums
      // for strings a and b
      vector<vector<int> > elements1
        = elements[j - 1];
      vector<vector<int> > elements2 = elements[j];
 
      int p1 = 0;
      int p2 = 0;
 
      // Check if the lengths of characters
      // differ; if they do, then
      // no valid subsequence
      // with that character can be generated.
      // So for all other letters,
      // add that character to its Set.
      // Otherwise, check the count
      // of each character
      // at every position where
      // letter i appears in both strings
      if (elements1[a.size() - 1][i]
          != elements2[b.size() - 1][i]) {
        for (auto key : requiredRemovals) {
          requiredRemovals[key.first].insert(i);
        }
      }
      else {
        // Iterate through both strings
        // using p1 for all characters
        // in the first string
        // and p2 for all characters
        // in the second string
        while (p1 < a.size() && p2 < b.size()) {
          // Skip to the next occurrence of
          // character i in string a
          while (p1 < a.size()
                 && (a[p1] - 'a') != i)
            p1++;
          // Skip to the next occurrence of
          // character i in string b
          while (p2 < b.size()
                 && (b[p2] - 'a') != i)
            p2++;
 
          // Compare the count of each
          // character to check if they match
          // in both strings
          if (p1 < a.size() && p2 < b.size()) {
            // Iterate over
            // their prefix sums
            for (int k = 0; k < numElements;
                 k++) {
              if (elements1[p1][k]
                  != elements2[p2][k])
                requiredRemovals[i].insert(
                k);
            }
          }
          p1++;
          p2++;
        }
      }
    }
  }
  vector<bool> res;
  // Read Q queries
  for (int i = 0; i < Q; i++) {
    // st = new StringTokenizer(br.readLine());
    // String q = st.nextToken();
    set<int> Union;
    // generate a combined set of all characters
    // which must be removed for a valid subsequence
    // to be created with the query string
    for (char c : queries[i])
      Union.insert(requiredRemovals.begin(), requiredRemovals.end());
    bool ans = true;
 
    // if there are any contradictions in the query,
    // then the answer will be false
    for (char c : queries[i]) {
      if (Union.find(c - 'a') != Union.end())
        ans = false;
    }
    res.push_back(ans);
  }
  return res;
}
 
// Driver Code
int main()
{
  int N = 3;
  vector<string> arr;
  arr.push_back("accbad");
  arr.push_back("abcacd");
  arr.push_back("cacbda");
  int Q = 6;
  string queries[6];
 
  queries[0] = "a";
  queries[1] = "ab";
  queries[2] = "ad";
  queries[3] = "bd";
  queries[4] = "bcd";
  queries[5] = "abd";
 
  // Function call
  vector<bool> ans = isPossible(N, arr, Q, queries);
  for (bool val : ans)
    cout << val << endl;
}
 
// This code is contributed by nebula_242


Java




// Java code to implement the approach
 
import java.io.*;
import java.util.*;
 
public class SubsequenceQueries {
 
    // Function to check if
    // the subsequences formed are the same
    public static ArrayList<Boolean>
    isPossible(int N, ArrayList<String> arr, int Q,
               String queries[])
    {
        // For 26 letters
        final int numElements = 26;
 
        // Generate prefix sums (for each letter)
        // for each string
        ArrayList<int[][]> elements
            = new ArrayList<>();
        for (int i = 0; i < N; i++) {
 
            // Create a new prefix sum array
            // and add it to the array list
            elements.add(new int[arr.get(i).length()]
                                [numElements]);
            int[][] tmp = elements.get(i);
 
            // Build the prefix sum
            // at each position in the string
            for (int j = 0; j < arr.get(i).length();
                 j++) {
                for (int k = 0; k < numElements;
                     k++) {
                    if (j != 0)
                        tmp[j][k] = tmp[j - 1][k];
                }
 
                // ASCII to int conversion
                // for lowercase letters
                tmp[j][arr.get(i).charAt(j) - 97]++;
            }
        }
 
        // Generate the set of characters
        // which are necessary to remove.
        // Each mapping is the set
        // corresponding of characters
        // which need to be removed.
        // for each letter in order for a
        // subsequence to be generated.
        HashMap<Integer, Set<Integer> > requiredRemovals
            = new HashMap<>();
        for (int i = 0; i < numElements; i++)
            requiredRemovals.put(i, new HashSet<Integer>());
 
        // Iterate over all the characters
        // (in the alphabet in this case)
        for (int i = 0; i < numElements; i++) {
 
            // For each character,
            // go through all M strings
            // to generate prefix sums
            for (int j = 1; j < N; j++) {
 
                // String a stores
                // the previous string (j-1)
                // string b stores
                // the current string (j)
                String a = arr.get(j - 1);
                String b = arr.get(j);
 
                // Store the prefix sums
                // for strings a and b
                int[][] elements1
                    = elements.get(j - 1);
                int[][] elements2
                    = elements.get(j);
 
                int p1 = 0;
                int p2 = 0;
 
                // Check if the lengths of characters
                // differ; if they do, then
                // no valid subsequence
                // with that character can be generated.
                // So for all other letters,
                // add that character to its Set.
                // Otherwise, check the count
                // of each character
                // at every position where
                // letter i appears in both strings
                if (elements1[a.length() - 1][i]
                    != elements2[b.length() - 1][i]) {
                    for (int key :
                         requiredRemovals.keySet())
                        requiredRemovals.get(key).add(i);
                }
                else {
                    // Iterate through both strings
                    // using p1 for all characters
                    // in the first string
                    // and p2 for all characters
                    // in the second string
                    while (p1 < a.length()
                           && p2 < b.length()) {
 
                        // Skip to the next occurrence of
                        // character i in string a
                        while (p1 < a.length()
                               && a.charAt(p1)
                                          - 97
                                      != i) {
                            p1++;
                        }
 
                        // Skip to the next occurrence of
                        // character i in string b
                        while (p2 < b.length()
                               && b.charAt(p2)
                                          - 97
                                      != i) {
                            p2++;
                        }
 
                        // Compare the count of each
                        // character to check if they match
                        // in both strings
                        if (p1 < a.length()
                            && p2 < b.length()) {
 
                            // Iterate over
                            // their prefix sums
                            for (int k = 0;
                                 k < numElements;
                                 k++) {
                                if (elements1[p1][k]
                                    != elements2[p2][k])
                                    requiredRemovals.get(i)
                                        .add(k);
                            }
                        }
                        p1++;
                        p2++;
                    }
                }
            }
        }
 
        ArrayList<Boolean> res
            = new ArrayList<Boolean>();
 
        // Read in Q queries
        for (int i = 0; i < Q; i++) {
 
            // st = new StringTokenizer(br.readLine());
            // String q = st.nextToken();
            Set<Integer> union
                = new HashSet<Integer>();
 
            // generate a combined set of all characters
            // which must be removed for a valid subsequence
            // to be created with the query string
            for (char c : queries[i].toCharArray())
                union.addAll(requiredRemovals.get(c - 97));
            boolean ans = true;
 
            // if there are any contradictions in the query,
            // then the answer will be false
            for (char c : queries[i].toCharArray()) {
                if (union.contains(c - 97))
                    ans = false;
            }
 
            res.add(ans);
        }
        return res;
    }
 
    // Driver code
    public static void main(String[] args)
        throws IOException
    {
        int N = 3;
        ArrayList<String> arr
            = new ArrayList<String>();
        arr.add("accbad");
        arr.add("abcacd");
        arr.add("cacbda");
        int Q = 6;
        String queries[]
            = new String[6];
        queries[0] = "a";
        queries[1] = "ab";
        queries[2] = "ad";
        queries[3] = "bd";
        queries[4] = "bcd";
        queries[5] = "abd";
 
        // Function call
        ArrayList<Boolean> ans
            = isPossible(N, arr, Q, queries);
        for (boolean val : ans)
            System.out.println(val);
    }
}


Python3




# python code to implement the approach
from typing import List, Set
from collections import defaultdict
 
# function to check if the subsequences formed are the same
def isPossible(N: int, arr: List[str], Q: int,
               queries: List[str]) -> List[bool]:
    # For 26 letters
    numElements = 26
    # Generate prefix sums (for each letter)
    # for each string
    elements = []
    for i in range(N):
       
        # Create a new prefix sum array
        # and add it to the array list
        tmp = [[0] * numElements for _ in range(len(arr[i]))]
         
        # Build the prefix sum
        # at each position in the string
        for j in range(len(arr[i])):
            for k in range(numElements):
                if j != 0:
                    tmp[j][k] = tmp[j-1][k]
                     
            # ASCII to int conversion
            # for lowercase letters
            tmp[j][ord(arr[i][j]) - ord('a')] += 1
        elements.append(tmp)
         
    # Generate the set of characters
    # which are necessary to remove.
    # Each mapping is the set
    # corresponding of characters
    # which need to be removed.
    # for each letter in order for a
    # subsequence to be generated.
    requiredRemovals = defaultdict(set)
    for i in range(numElements):
        requiredRemovals[i] = set()
    # Iterate over all the characters
    # (in the alphabet in this case)
    for i in range(numElements):
       
        # For each character,
        # go through all M strings
        # to generate prefix sums
        for j in range(1, N):
           
            # String a stores
            # the previous string (j-1)
            # string b stores
            # the current string (j)
            a = arr[j-1]
            b = arr[j]
             
            # store the prefix sum
            # for string a  and b
            elements1 = elements[j-1]
            elements2 = elements[j]
            p1 = 0
            p2 = 0
             
            # Check if the lengths of characters
            # differ; if they do, then
            # no valid subsequence
            # with that character can be generated.
            # So for all other letters,
            # add that character to its Set.
            # Otherwise, check the count
            # of each character
            # at every position where
            # letter i appears in both strings
            if elements1[len(a)-1][i] != elements2[len(b)-1][i]:
                for key in requiredRemovals:
                    requiredRemovals[key].add(i)
            else:
                # Iterate through both strings
                # using p1 for all characters
                # in the first string
                # and p2 for all characters
                # in the second string
                while p1 < len(a) and p2 < len(b):
                    # Skip to the next occurrence of
                    # character i in string a
                    while p1 < len(a) and ord(a[p1]) - ord('a') != i:
                        p1 += 1
                        # Skip to the next occurrence of
                        # character i in string b
                    while p2 < len(b) and ord(b[p2]) - ord('a') != i:
                        p2 += 1
                        # Compare the count of each
                        # character to check if they match
                        # in both strings
                    if p1 < len(a) and p2 < len(b):
                        # Iterate over their prefix sums
                        for k in range(numElements):
                            if elements1[p1][k] != elements2[p2][k]:
                                requiredRemovals[i].add(k)
                    p1 += 1
                    p2 += 1
 
    res = []
    # Read Q queries
    for i in range(Q):
        # generate a combined set of all characters
        # which must be removed for a valid subsequence
        # to be created with the query string
        Union = set()
        # if there are any contradictions in the query,
        # then the answer will be false
        for c in queries[i]:
            Union |= requiredRemovals[ord(c) - ord('a')]
        ans = all(ord(c) - ord('a') not in Union for c in queries[i])
        res.append(ans)
 
    return res
 
# Driver Code
if __name__ == "__main__":
    N = 3
    arr = ["accbad", "abcacd", "cacbda"]
    Q = 6
    queries = ["a", "ab", "ad", "bd", "bcd", "abd"]
 
    # Function call
    ans = isPossible(N, arr, Q, queries)
    for val in ans:
        print(int(val))


C#




// C# program to implement above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // For 26 letters
    readonly public static int numElements = 26;
 
    // Function to check if
    // the subsequences formed are the same
    public static List<bool> isPossible(int N, List<String> arr, int Q, String[] queries)
    {
 
        // Generate prefix sums (for each letter)
        // for each string
        List<int[, ]> elements = new List<int[, ]>();
        for (int i = 0 ; i < N ; i++) {
 
            // Create a new prefix sum array
            // and add it to the array list
            elements.Add(new int[arr[i].Length, numElements]);
 
            // Build the prefix sum
            // at each position in the string
            for (int j = 0 ; j < arr[i].Length ; j++) {
                for (int k = 0 ; k < numElements ; k++) {
                    if(j!=0){
                        elements[i][j, k] = elements[i][j - 1, k];
                    }
                }
 
                // ASCII to int conversion
                // for lowercase letters
                elements[i][j, ((int)arr[i][j] - 97)]++;
            }
        }
 
        // Generate the set of characters
        // which are necessary to remove.
        // Each mapping is the set
        // corresponding of characters
        // which need to be removed.
        // for each letter in order for a
        // subsequence to be generated.
        SortedDictionary<int, SortedSet<int>> requiredRemovals = new SortedDictionary<int, SortedSet<int>>();
        for (int i = 0 ; i < numElements ; i++){
            requiredRemovals.Add(i, new SortedSet<int>());
        }
 
        // Iterate over all the characters
        // (in the alphabet in this case)
        for (int i = 0 ; i < numElements ; i++) {
 
            // For each character,
            // go through all M strings
            // to generate prefix sums
            for (int j = 1 ; j < N ; j++) {
 
                // String a stores
                // the previous string (j-1)
                // string b stores
                // the current string (j)
                String a = arr[j - 1];
                String b = arr[j];
 
                // Store the prefix sums
                // for strings a and b
                int[, ] elements1 = elements[j - 1];
                int[, ] elements2 = elements[j];
 
                int p1 = 0;
                int p2 = 0;
 
                // Check if the lengths of characters
                // differ; if they do, then
                // no valid subsequence
                // with that character can be generated.
                // So for all other letters,
                // add that character to its Set.
                // Otherwise, check the count
                // of each character
                // at every position where
                // letter i appears in both strings
                if (elements1[a.Length - 1, i] != elements2[b.Length - 1, i]) {
                    foreach( KeyValuePair<int, SortedSet<int>> pr in requiredRemovals){
                        requiredRemovals[pr.Key].Add(i);
                    }
                }
                else {
                    // Iterate through both strings
                    // using p1 for all characters
                    // in the first string
                    // and p2 for all characters
                    // in the second string
                    while (p1 < a.Length && p2 < b.Length) {
 
                        // Skip to the next occurrence of
                        // character i in string a
                        while (p1 < a.Length && ((int)a[p1] - 97) != i) {
                            p1++;
                        }
 
                        // Skip to the next occurrence of
                        // character i in string b
                        while (p2 < b.Length && ((int)b[p2] - 97) != i) {
                            p2++;
                        }
 
                        // Compare the count of each
                        // character to check if they match
                        // in both strings
                        if (p1 < a.Length && p2 < b.Length) {
 
                            // Iterate over
                            // their prefix sums
                            for (int k = 0 ; k < numElements; k++) {
                                if (elements1[p1, k] != elements2[p2, k]){
                                    requiredRemovals[i].Add(k);
                                }
                            }
                        }
                        p1++;
                        p2++;
                    }
                }
            }
        }
 
        List<bool> res = new List<bool>();
 
        // Read in Q queries
        for (int i = 0; i < Q; i++) {
 
            // st = new StringTokenizer(br.readLine());
            // String q = st.nextToken();
            SortedSet<int> union = new SortedSet<int>();
 
            // generate a combined set of all characters
            // which must be removed for a valid subsequence
            // to be created with the query string
            foreach (char c in queries[i].ToCharArray()){
                foreach(int x in requiredRemovals[((int)c - 97)]){
                    union.Add(x);
                }
            }
            bool ans = true;
 
            // if there are any contradictions in the query,
            // then the answer will be false
            foreach (char c in queries[i].ToCharArray()) {
                if (union.Contains((int)c - 97)){
                    ans = false;
                }
            }
 
            res.Add(ans);
        }
        return res;
    }
 
 
    // Driver Code
    public static void Main(string[] args){
         
        int N = 3;
        List<String> arr = new List<String>();
        arr.Add("accbad");
        arr.Add("abcacd");
        arr.Add("cacbda");
 
        int Q = 6;
        String[] queries = new String[6];
        queries[0] = "a";
        queries[1] = "ab";
        queries[2] = "ad";
        queries[3] = "bd";
        queries[4] = "bcd";
        queries[5] = "abd";
 
        // Function call
        List<bool> ans = isPossible(N, arr, Q, queries);
        foreach(bool val in ans){
            Console.Write(val + "\n");
        }
 
    }
}
 
// This code is contributed by subhamgoyal2014.


Javascript




// JavaScript code
 
// Function to check if the subsequences formed are the same
function isPossible(N, arr, Q, queries) {
  // For 26 letters
  const numElements = 26;
 
  // Generate prefix sums (for each letter)
  // for each string
  let elements = [];
  for (let i = 0; i < N; i++) {
 
    // Create a new prefix sum array
    // and add it to the array list
    let tmp = [];
    for (let j = 0; j < arr[i].length; j++) {
      tmp.push(Array(numElements).fill(0));
    }
 
    // Build the prefix sum
    // at each position in the string
    for (let j = 0; j < arr[i].length; j++) {
      for (let k = 0; k < numElements; k++) {
        if (j != 0)
          tmp[j][k] = tmp[j - 1][k];
      }
      // ASCII to int conversion
      // for lowercase letters
      tmp[j][arr[i][j].charCodeAt(0) - 97]++;
    }
    elements.push(tmp);
  }
  // Generate the set of characters
  // which are necessary to remove.
  // Each mapping is the set
  // corresponding of characters
  // which need to be removed.
  // for each letter in order for a
  // subsequence to be generated.
  let requiredRemovals = {};
  for (let i = 0; i < numElements; i++)
    requiredRemovals[i] = new Set();
  // Iterate over all the characters
  // (in the alphabet in this case)
  for (let i = 0; i < numElements; i++) {
 
    // For each character,
    // go through all M strings
    // to generate prefix sums
    for (let j = 1; j < N; j++) {
      // String a stores
      // the previous string (j-1)
      // string b stores
      // the current string (j)
      let a = arr[j - 1];
      let b = arr[j];
 
      // Store the prefix sums
      // for strings a and b
      let elements1 = elements[j - 1];
      let elements2 = elements[j];
 
      let p1 = 0;
      let p2 = 0;
 
      // Check if the lengths of characters
      // differ; if they do, then
      // no valid subsequence
      // with that character can be generated.
      // So for all other letters,
      // add that character to its Set.
      // Otherwise, check the count
      // of each character
      // at every position where
      // letter i appears in both strings
      if (elements1[a.length - 1][i]
          != elements2[b.length - 1][i]) {
        for (let key of Object.keys(requiredRemovals)) {
          requiredRemovals[key].add(i);
        }
      } else {
        // Iterate through both strings
        // using p1 for all characters
        // in the first string
        // and p2 for all characters
        // in the second string
        while (p1 < a.length && p2 < b.length) {
          // Skip to the next occurrence of
          // character i in string a
          while (p1 < a.length
                 && (a.charCodeAt(p1) - 97) != i)
            p1++;
          // Skip to the next occurrence of
          // character i in string b
          while (p2 < b.length
                 && (b.charCodeAt(p2) - 97) != i)
            p2++;
 
          // Compare the count of each
          // character to check if they match
          // in both strings
          if (p1 < a.length && p2 < b.length) {
            // Iterate over
            // their prefix sums
            for (let k = 0; k < numElements;
                 k++) {
              if (elements1[p1][k]
                  != elements2[p2][k])
                requiredRemovals[i].add(
                k);
            }
          }
          p1++;
          p2++;
        }
      }
    }
  }
  let res = [];
  // Read Q queries
  for (let i = 0; i < Q; i++) {
    let Union = new Set();
     
    // generate a combined set of all characters
    // which must be removed for a valid subsequence
    // to be created with the query string
    for (let c of queries[i])
      Union.add(...requiredRemovals);
    let ans = true;
 
    // if there are any contradictions in the query,
    // then the answer will be false
    for (let c of queries[i]) {
      if (Union.has(c.charCodeAt(0) - 97))
        ans = false;
    }
    res.push(ans);
  }
  return res;
}
 
// Driver Code
let N = 3;
let arr = ["accbad", "abcacd", "cacbda"];
let Q = 6;
let queries = ["a", "ab", "ad", "bd", "bcd", "abd"];
 
// Function call
let ans = isPossible(N, arr, Q, queries);
for (let val of ans)
  console.log(val);
   
// This code is contributed by akashish__


Output

1
1
0
1
0
0

Time Complexity: O(C2 * N + Q * N)
Auxiliary Space: O(C2 * N) where C = 26



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads