Given two strings S and T and a 2D array replace[][], where replace[i] = {oldChar, newChar} represents that the character oldChar of T is replaced with newChar. The task is to find if it is possible to make string T a substring of S by replacing characters according to the replace array.
Note: Each character in T cannot be replaced more than once.
Example:
Input: S = “hoog3e7bar”, T = “geek”, replace = {{‘e’, ‘3’}, {‘t’, ‘7’}, {‘k’, ‘8’}}
Output: true
Explanation: Replace the first ‘e’ in T with ‘3’ and ‘k’ in T with ‘7’.
Now T = “g3e7” is a substring of S, so we return true.Input: S = “gooleetbar”, T = “g00l”, replace = {{‘o’, ‘0’}}
Output: false
Approach: The problem can be solved using Hashing based on the following idea:
Keep a datastructure for storing all the mapping of replace array. Enumerate all substrings of S with the same length as T, and compare each substring to S for equality.
Follow the steps below to implement the above approach:
- Initialize a map say unmap, for mapping all the characters that oldChar can replace with newChar.
- Iterate over the replace array and do the mapping.
- Iterate over all the subarray of S of length equals to given string T.
- Check if the character in S is not equal to the character in T.
- If not equal then check if there exists any replacement of T[j] in unmap.
- If a mapping exists then continue.
- Otherwise, break from the current iteration and look for the other substring.
- Check if the character in S is not equal to the character in T.
- If we successfully find a valid substring, then return true.
- Otherwise, return false.
Below is the implementation of the above approach.
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to check if the string // can be made substring of S bool match(string S, string T,
vector<vector< char > >& replace)
{ // Initialise a map say unmap, for
// mapping all the characters that
// oldChar can replace with newChar
unordered_map< char , unordered_set< char > > unmap;
int m = S.size(), n = T.size();
// Iterate over the replace array
// and map in unmap
for ( auto c : replace) {
unmap].insert(c[1]);
}
// Iterate over all the subarray in S
// of length equals to given string T.
for ( int i = 0; i < m - n + 1; i++) {
bool flag = true ;
for ( int j = 0; j < n; j++) {
// Check if the character in S
// is not equal to character
// in T. If not equal then
// check if there exist any
// replacement of T[j] in unmap.
if (S[i + j] != T[j]) {
// If mapping exists, continue
if (unmap[T[j]].find(S[i + j])
!= unmap[T[j]].end()) {
continue ;
}
// Otherwise, break from
// current iteration and look
// for the another substring.
else {
flag = false ;
break ;
}
}
}
// If we successfully found valid
// substring, then return true
if (flag)
return true ;
}
// Otherwise, return false
return false ;
} // Drivers code int main()
{ string S = "hoog3e7bar" , T = "geek" ;
vector<vector< char > > replace
= { { 'e' , '3' }, { 't' , '7' }, { 'k' , '7' } };
// Function call
bool result = match(S, T, replace);
if (result)
cout << "YES" << endl;
else
cout << "NO" << endl;
return 0;
} |
// Java code to implement the approach import java.io.*;
import java.util.*;
class GFG {
// Function to check if the string
// can be made substring of S
static boolean match(String S, String T,
char [][] replace)
{
// Initialise a map for mapping all
// the characters that oldChar can
// replace with newChar
Map<Character, Set<Character> > unmap
= new HashMap<>();
int m = S.length(), n = T.length();
// Iterate over the replace array
// and map in unmap
for ( char [] c : replace) {
if (!unmap.containsKey(c[ 0 ])) {
unmap.put(c[ 0 ], new HashSet<>());
}
unmap.get(c[ 0 ]).add(c[ 1 ]);
}
// Iterate over all the subarray in S
// of length equals to given string T.
for ( int i = 0 ; i < m - n + 1 ; i++) {
boolean flag = true ;
for ( int j = 0 ; j < n; j++)
{
// Check if the character in S
// is not equal to character
// in T. If not equal then
// check if there exist any
// replacement of T[j] in unmap.
if (S.charAt(i + j) != T.charAt(j))
{
// If mapping exists, continue
if (unmap.containsKey(T.charAt(j))
&& unmap.get(T.charAt(j))
.contains(S.charAt(i + j))) {
continue ;
}
// Otherwise, break from
// current iteration and look
// for the another substring.
else {
flag = false ;
break ;
}
}
}
// If we successfully found valid
// substring, then return true
if (flag)
return true ;
}
// Otherwise, return false
return false ;
}
public static void main(String[] args)
{
String S = "hoog3e7bar" , T = "geek" ;
char [][] replace
= { { 'e' , '3' }, { 't' , '7' }, { 'k' , '7' } };
// Function call
boolean result = match(S, T, replace);
if (result) {
System.out.println( "YES" );
}
else {
System.out.println( "NO" );
}
}
} // This code is contributed by lokeshmvs21. |
# Python code to implement the approach # Function to check if the string # can be made substring of S def match(S,T,replace):
# Initialise a map say unmap, for
# mapping all the characters that
# oldChar can replace with newChar
unmap = {}
m = len (S)
n = len (T)
# Iterate over the replace array
# and map in unmap
for c in replace:
unmap] = c[ 1 ]
# Iterate over all the subarray in S
# of length equals to given string T.
for i in range (m - n + 1 ):
flag = True
for j in range (n):
# Check if the character in S
# is not equal to character
# in T. If not equal then
# check if there exist any
# replacement of T[j] in unmap.
if (S[i + j]! = T[j]):
# If mapping exists, continue
if S[i + j] in unmap.values():
continue
# Otherwise, break from
# current iteration and look
# for the another substring.
else :
flag = False
break
# If we successfully found valid
# substring, then return true
if (flag):
return True
# Otherwise, return false
return False
# Driver code S = "hoog3e7bar"
T = "geek"
replace = [[ 'e' , '3' ],[ 't' , '7' ],[ 'k' , '7' ]]
# Function call result = match(S,T,replace)
if (result):
print ( "Yes" )
else :
print ( "No" )
# This code is contributed by Pushpesh Raj. |
// JavaScript code for the above approach
// Function to check if the string
// can be made substring of S
function match(S, T, replace)
{
// Initialise a map for mapping all
// the characters that oldChar can
// replace with newChar
let unmap = new Map();
let m = S.length;
let n = T.length;
// Iterate over the replace array
// and map in unmap
for (let c of replace) {
if (!unmap.has(c[0])) {
unmap.set(c[0], new Set());
}
unmap.get(c[0]).add(c[1]);
}
// Iterate over all the subarray in S
// of length equals to given string T.
for (let i = 0; i < m - n + 1; i++) {
let flag = true ;
for (let j = 0; j < n; j++)
{
// Check if the character in S
// is not equal to character
// in T. If not equal then
// check if there exist any
// replacement of T[j] in unmap.
if (S[i + j] != T[j]) {
// If mapping exists, continue
if (unmap.has(T[j]) && unmap.get(T[j]).has(S[i + j])) {
continue ;
}
// Otherwise, break from
// current iteration and look
// for the another substring.
else {
flag = false ;
break ;
}
}
}
// If we successfully found valid
// substring, then return true
if (flag) return true ;
}
// Otherwise, return false
return false ;
}
// Driver code
let S = "hoog3e7bar" ;
let T = "geek" ;
let replace = [
[ 'e' , '3' ],
[ 't' , '7' ],
[ 'k' , '7' ],
];
// Function call
let result = match(S, T, replace);
if (result) {
console.log( "YES" );
} else {
console.log( "NO" );
}
// This code is contributed by Potta Lokesh |
using System;
using System;
using System.Collections.Generic;
public class Program {
// Function to check if the string
// can be made substring of S
static bool Match( string S, string T, char [][] replace)
{
// Initialise a map for mapping all
// the characters that oldChar can
// replace with newChar
Dictionary< char , HashSet< char > > unmap
= new Dictionary< char , HashSet< char > >();
int m = S.Length, n = T.Length;
// Iterate over the replace array
// and map in unmap
foreach ( char [] c in replace)
{
if (!unmap.ContainsKey(c[0])) {
unmap.Add(c[0], new HashSet< char >());
}
unmap].Add(c[1]);
}
// Iterate over all the subarray in S
// of length equals to given string T.
for ( int i = 0; i < m - n + 1; i++) {
bool flag = true ;
for ( int j = 0; j < n; j++) {
// Check if the character in S
// is not equal to character
// in T. If not equal then
// check if there exist any
// replacement of T[j] in unmap.
if (S[i + j] != T[j]) {
// If mapping exists, continue
if (unmap.ContainsKey(T[j])
&& unmap[T[j]].Contains(S[i + j])) {
continue ;
}
// Otherwise, break from
// current iteration and look
// for the another substring.
else {
flag = false ;
break ;
}
}
}
// If we successfully found valid
// substring, then return true
if (flag)
return true ;
}
// Otherwise, return false
return false ;
}
static public void Main( string [] args)
{
string S = "hoog3e7bar" , T = "geek" ;
char [][] replace = { new char [] { 'e' , '3' },
new char [] { 't' , '7' },
new char [] { 'k' , '7' } };
// Function call
bool result = Match(S, T, replace);
if (result) {
Console.WriteLine( "YES" );
}
else {
Console.WriteLine( "NO" );
}
}
} |
YES
Time Complexity: O(N * M) where N and M are the length of the strings T and S respectively.
Auxiliary Space: O(D) where D is the size of the array replace[][].
Related Articles:
- Introduction to String – Data Structures and Algorithms Tutorials
- Introduction to Hashing – Data Structures and Algorithms Tutorials