Check if a string can be transformed to another by sorting substrings
Last Updated :
27 Jun, 2021
Given two strings str1 and str2, each of length N and consisting of lowercase English alphabets only, the task is to check if string str1 can be transformed to string str2 by performing the following operations any number of times.
Examples :
Input: str1 = “hdecb”, str2 = “cdheb”
Output: Yes
Explanation:
Sorting the substring “ec” in str1 modifies the string to “hdceb”
Sorting the substring “hdc” in str1 modifies the string to “cdheb”.
Since, the modified string is same as str2, the answer is Yes.
Input: str1 = “abcdef”, str2 = “dacbfe”
Output: No
Approach: Follow the steps below to solve the problem:
- Observe that, in the string str1, if there are two characters str1[i] and str2[j] such that str1[i] < str1[j], then these characters can be swapped.
- In other words, it is possible to move a character freely to the left, until it encounters a smaller character. For example, “acdb” can be converted to either “acbd“, “abcd” as ‘b‘ can be moved freely to the left until ‘a‘ occurs.
- Therefore, check if it is possible to move the required characters to the left, to their respective positions in the string str2.
- Store the indices of every character of string str1 in an array.
- Traverse the string str2, and for each character, check if the same character in str1 can be shifted to that position or not.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void canTransform(string& s, string& t)
{
int n = s.length();
vector< int > occur[26];
for ( int x = 0; x < n; x++) {
char ch = s[x] - 'a' ;
occur[ch].push_back(x);
}
vector< int > idx(26, 0);
bool poss = true ;
for ( int x = 0; x < n; x++) {
char ch = t[x] - 'a' ;
if (idx[ch] >= occur[ch].size()) {
poss = false ;
break ;
}
for ( int small = 0; small < ch; small++) {
if (idx[small] < occur[small].size()
&& occur[small][idx[small]]
< occur[ch][idx[ch]]) {
poss = false ;
break ;
}
}
idx[ch]++;
}
if (poss) {
cout << "Yes" << endl;
}
else {
cout << "No" << endl;
}
}
int main()
{
string s, t;
s = "hdecb" ;
t = "cdheb" ;
canTransform(s, t);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void canTransform(String s,
String t)
{
int n = s.length();
Vector<Integer> occur[] = new Vector[ 26 ];
for ( int i = 0 ; i < occur.length; i++)
occur[i] = new Vector<Integer>();
for ( int x = 0 ; x < n; x++)
{
char ch = ( char )(s.charAt(x) - 'a' );
occur[ch].add(x);
}
int []idx = new int [ 26 ];
boolean poss = true ;
for ( int x = 0 ; x < n; x++)
{
char ch = ( char )(t.charAt(x) - 'a' );
if (idx[ch] >= occur[ch].size())
{
poss = false ;
break ;
}
for ( int small = 0 ; small < ch; small++)
{
if (idx[small] < occur[small].size() &&
occur[small].get(idx[small]) <
occur[ch].get(idx[ch]))
{
poss = false ;
break ;
}
}
idx[ch]++;
}
if (poss)
{
System.out.print( "Yes" + "\n" );
}
else
{
System.out.print( "No" + "\n" );
}
}
public static void main(String[] args)
{
String s, t;
s = "hdecb" ;
t = "cdheb" ;
canTransform(s, t);
}
}
|
Python3
def canTransform(s, t):
n = len (s)
occur = [[] for i in range ( 26 )]
for x in range (n):
ch = ord (s[x]) - ord ( 'a' )
occur[ch].append(x)
idx = [ 0 ] * ( 26 )
poss = True
for x in range (n):
ch = ord (t[x]) - ord ( 'a' )
if (idx[ch] > = len (occur[ch])):
poss = False
break
for small in range (ch):
if (idx[small] < len (occur[small]) and
occur[small][idx[small]] <
occur[ch][idx[ch]]):
poss = False
break
idx[ch] + = 1
if (poss):
print ( "Yes" )
else :
print ( "No" )
if __name__ = = '__main__' :
s = "hdecb"
t = "cdheb"
canTransform(s, t)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void canTransform(String s,
String t)
{
int n = s.Length;
List< int > []occur = new List< int >[26];
for ( int i = 0; i < occur.Length; i++)
occur[i] = new List< int >();
for ( int x = 0; x < n; x++)
{
char ch = ( char )(s[x] - 'a' );
occur[ch].Add(x);
}
int []idx = new int [26];
bool poss = true ;
for ( int x = 0; x < n; x++)
{
char ch = ( char )(t[x] - 'a' );
if (idx[ch] >= occur[ch].Count)
{
poss = false ;
break ;
}
for ( int small = 0; small < ch; small++)
{
if (idx[small] < occur[small].Count &&
occur[small][idx[small]] <
occur[ch][idx[ch]])
{
poss = false ;
break ;
}
}
idx[ch]++;
}
if (poss)
{
Console.Write( "Yes" + "\n" );
}
else
{
Console.Write( "No" + "\n" );
}
}
public static void Main(String[] args)
{
String s, t;
s = "hdecb" ;
t = "cdheb" ;
canTransform(s, t);
}
}
|
Javascript
<script>
function canTransform(s, t)
{
var n = s.length;
var occur = Array.from(Array(26), ()=> new Array());
for ( var x = 0; x < n; x++) {
var ch = s[x].charCodeAt(0) - 'a' .charCodeAt(0);
occur[ch].push(x);
}
var idx = Array(26).fill(0);
var poss = true ;
for ( var x = 0; x < n; x++) {
var ch = t[x].charCodeAt(0) - 'a' .charCodeAt(0);
if (idx[ch] >= occur[ch].length) {
poss = false ;
break ;
}
for ( var small = 0; small < ch; small++) {
if (idx[small] < occur[small].length
&& occur[small][idx[small]]
< occur[ch][idx[ch]]) {
poss = false ;
break ;
}
}
idx[ch]++;
}
if (poss) {
document.write( "Yes" );
}
else {
document.write( "No" );
}
}
var s, t;
s = "hdecb" ;
t = "cdheb" ;
canTransform(s, t);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...