Check if a string can be formed from another string using given constraints
Last Updated :
23 May, 2022
Given two strings S1 and S2(all characters are in lower-case). The task is to check if S2 can be formed from S1 using given constraints:
1. Characters of S2 is there in S1 if there are two ‘a’ in S2, then S1 should have two ‘a’ also.
2. If any character of S2 is not present in S1, check if the previous two ASCII characters are there in S1. e.g., if ‘e’ is there in S2 and not in S1, then ‘c’ and ‘d’ can be used from S1 to make ‘e’.
Note: All characters from S1 can be used only once.
Examples:
Input: S= abbat, W= cat
Output: YES
‘c’ is formed from ‘a’ and ‘b’, ‘a’ and ‘t’ is present in S1.
Input: S= abbt, W= cat
Output: NO
‘c’ is formed from ‘a’ and ‘b’, but to form the next character
‘a’ in S2, there is no more unused ‘a’ left in S1.
Approach: The above problem can be solved using hashing. The count of all the characters in S1 is stored in a hash-table. Traverse in the string, and check if the character in S2 is there in the hash-table, reduce the count of that particular character in the hash-table. If the character is not there in the hash-table, check if the previous two ASCII characters are there in the hash-table, then reduce the count of the previous two ASCII characters in the hash-table. If all the characters can be formed from S1 using the given constraints, the string S2 can be formed from S1, else it cannot be formed.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool check(string S1, string S2)
{
int n1 = S1.size();
int n2 = S2.size();
unordered_map< int , int > mp;
for ( int i = 0; i < n1; i++) {
mp[S1[i]]++;
}
for ( int i = 0; i < n2; i++) {
if (mp[S2[i]]) {
mp[S2[i]]--;
}
else if (mp[S2[i] - 1] && mp[S2[i] - 2]) {
mp[S2[i] - 1]--;
mp[S2[i] - 2]--;
}
else {
return false ;
}
}
return true ;
}
int main()
{
string S1 = "abbat" ;
string S2 = "cat" ;
if (check(S1, S2))
cout << "YES" ;
else
cout << "NO" ;
}
|
Java
import java.util.*;
class GFG
{
static boolean check(String S1, String S2)
{
int n1 = S1.length();
int n2 = S2.length();
HashMap<Integer,Integer> mp =
new HashMap<Integer,Integer>();
for ( int i = 0 ; i < n1; i++)
{
if (mp.containsKey(( int )S1.charAt(i)))
{
mp.put(( int )S1.charAt(i),
mp.get(( int )S1.charAt(i)) + 1 );
}
else
{
mp.put(( int )S1.charAt(i), 1 );
}
}
for ( int i = 0 ; i < n2; i++)
{
if (mp.containsKey(( int )S2.charAt(i)))
{
mp.put(( int )S2.charAt(i),
mp.get(( int )S2.charAt(i)) - 1 );
}
else if (mp.containsKey(S2.charAt(i)- 1 ) &&
mp.containsKey(S2.charAt(i)- 2 ))
{
mp.put((S2.charAt(i) - 1 ),
mp.get(S2.charAt(i) - 1 ) - 1 );
mp.put((S2.charAt(i) - 2 ),
mp.get(S2.charAt(i) - 2 ) - 1 );
}
else
{
return false ;
}
}
return true ;
}
public static void main(String[] args)
{
String S1 = "abbat" ;
String S2 = "cat" ;
if (check(S1, S2))
System.out.print( "YES" );
else
System.out.print( "NO" );
}
}
|
Python3
from collections import defaultdict
def check(S1, S2):
n1 = len (S1)
n2 = len (S2)
mp = defaultdict( lambda : 0 )
for i in range ( 0 , n1):
mp[S1[i]] + = 1
for i in range ( 0 , n2):
if mp[S2[i]]:
mp[S2[i]] - = 1
elif (mp[ chr ( ord (S2[i]) - 1 )] and
mp[ chr ( ord (S2[i]) - 2 )]):
mp[ chr ( ord (S2[i]) - 1 )] - = 1
mp[ chr ( ord (S2[i]) - 2 )] - = 1
else :
return False
return True
if __name__ = = "__main__" :
S1 = "abbat"
S2 = "cat"
if check(S1, S2):
print ( "YES" )
else :
print ( "NO" )
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static bool check(String S1, String S2)
{
int n1 = S1.Length;
int n2 = S2.Length;
Dictionary< int , int > mp =
new Dictionary< int , int >();
for ( int i = 0; i < n1; i++)
{
if (mp.ContainsKey(( int )S1[i]))
{
mp[( int )S1[i]] = mp[( int )S1[i]] + 1;
}
else
{
mp.Add(( int )S1[i], 1);
}
}
for ( int i = 0; i < n2; i++)
{
if (mp.ContainsKey(( int )S2[i]))
{
mp[( int )S2[i]] = mp[( int )S2[i]] - 1;
}
else if (mp.ContainsKey(S2[i] - 1) &&
mp.ContainsKey(S2[i] - 2))
{
mp[S2[i] - 1] = mp[S2[i] - 1] - 1;
mp[S2[i] - 2] = mp[S2[i] - 2] - 1;
}
else
{
return false ;
}
}
return true ;
}
public static void Main(String[] args)
{
String S1 = "abbat" ;
String S2 = "cat" ;
if (check(S1, S2))
Console.Write( "YES" );
else
Console.Write( "NO" );
}
}
|
Javascript
<script>
function check(S1, S2)
{
var n1 = S1.length;
var n2 = S2.length;
var mp = {};
for ( var i = 0; i < n1; i++)
{
if (mp.hasOwnProperty(S1[i]))
{
mp[S1[i]] = mp[S1[i]] + 1;
}
else
{
mp[S1[i]] = 1;
}
}
for ( var i = 0; i < n2; i++)
{
if (mp.hasOwnProperty(S2[i]))
{
mp[S2[i]] = mp[S2[i]] - 1;
}
else if (mp.hasOwnProperty(
String.fromCharCode(S2[i].charCodeAt(0) - 1)) &&
mp.hasOwnProperty(
String.fromCharCode(S2[i].charCodeAt(0) - 2)))
{
mp[String.fromCharCode(
S2[i].charCodeAt(0) - 1)] =
mp[String.fromCharCode(
S2[i].charCodeAt(0) - 1)] - 1;
mp[String.fromCharCode(
S2[i].charCodeAt(0) - 2)] =
mp[String.fromCharCode(
S2[i].charCodeAt(0) - 2)] - 1;
}
else
{
return false ;
}
}
return true ;
}
var S1 = "abbat" ;
var S2 = "cat" ;
if (check(S1, S2))
document.write( "YES" );
else
document.write( "NO" );
</script>
|
Time Complexity : O(m + n), where m is the length of string s1 and n is the length of string s2.
Auxiliary Space : O(m), where m is the length of string s1.
Share your thoughts in the comments
Please Login to comment...