Lexicographically minimum String possible
Last Updated :
11 Oct, 2023
Given three strings, S1, S2, and S3. The characters at the same index in S1 and S2 are considered equivalent and follow the transitive property, the task is to find and print the lexicographically smallest string that you can obtain from S3 by changing its characters to some other equivalent character obtained from S1 and S2. In other words, you need to replace the characters in S3 with their equivalent characters from S1 and S2 while maintaining the lexicographic order.
Examples:
Input: S1 = “abc” , S2 = “xyz” , S3 =” xazy”
Output: aacb
Explanation: ‘x’ replaced by ‘a’, ‘y’ is replaced by ‘b’ and ‘z’ is replaced by ‘c’
Input: S1 = “abc” , S2 = “xcd” , S3 =” xdc”
Output: abb
Explanation: {a, x} are equivalent, and {b, c, d} are equivalent, so x is replaced with a, d is replaced with b, and c is replaced with b.
Naïve approach: We can solve this problem using the below idea:
- Create a graph where s1[i] is connected with s2[i].
- then traverse string s3 from left to right and do the following.
- Call DFS for the s3[i] node and calculate the minimum character we can reach from node s3[i].
- assign this minimum character to s3[i].
- return string s3.
Time Complexity: O(N2)
Auxiliary Space: O ( 1 )
Efficient Approach: We can solve this problem optimally using the below idea:
Idea is to use the DSU {Disjoint Set Union}. We can connect the two characters which are mapped with each other and at the end we traverse the s3 string and assign every s3[i] to the parent of s3[i].
Follow the steps to solve the problem:
- Make a node for every character.
- Traverse in the string s1 and do Union of s1[i] with s2[i].
- When all Union operation is being done.
- Traverse in the s3 string and for every character of s3[i], assign it to its parent.
- Return the s3 string.
Below is the C++ implementation of the above idea :
C++
#include <bits/stdc++.h>
using namespace std;
int parent[1000];
int size[1000];
void make( int n)
{
parent[n] = n;
size[n] = 1;
}
int find( int n)
{
if (n == parent[n])
return n;
return parent[n] = find(parent[n]);
}
void Union( int a, int b)
{
a = find(a);
b = find(b);
if (a != b) {
if (a > b)
swap(a, b);
parent[b] = a;
size[a] += size[b];
}
}
string solve(string s1, string s2, string s3)
{
for ( char ch = 'a' ; ch <= 'z' ; ch++)
make(ch);
for ( int i = 0; i < s1.length(); i++) {
Union(s1[i], s2[i]);
}
for ( int i = 0; i < s3.length(); i++) {
s3[i] = find(s3[i]);
}
return s3;
}
int main()
{
string s1, s2, s3;
s1 = "abc" ;
s2 = "xcd" ;
s3 = "xdc" ;
cout << solve(s1, s2, s3);
return 0;
}
|
Java
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class GFG {
private Map<Character, Character> parent;
private Map<Character, Integer> size;
public GFG() {
parent = new HashMap<>();
size = new HashMap<>();
}
private void make(Character n) {
parent.put(n, n);
size.put(n, 1 );
}
private Character find(Character n) {
if (n.equals(parent.get(n)))
return n;
return parent.put(n, find(parent.get(n)));
}
private void Union(Character a, Character b) {
a = find(a);
b = find(b);
if (!a.equals(b)) {
if (a > b) {
Character temp = a;
a = b;
b = temp;
}
parent.put(b, a);
size.put(a, size.get(a) + size.get(b));
}
}
private String solve(String s1, String s2, String s3) {
for ( char ch = 'a' ; ch <= 'z' ; ch++) {
make(ch);
}
for ( int i = 0 ; i < s1.length(); i++) {
Union(s1.charAt(i), s2.charAt(i));
}
StringBuilder result = new StringBuilder();
for ( int i = 0 ; i < s3.length(); i++) {
result.append(find(s3.charAt(i)));
}
return result.toString();
}
public static void main(String[] args) {
GFG dsu = new GFG();
String s1 = "abc" ;
String s2 = "xcd" ;
String s3 = "xdc" ;
System.out.println(dsu.solve(s1, s2, s3));
}
}
|
Python3
parent = {}
size = {}
def make(n):
parent[n] = n
size[n] = 1
def find(n):
if n = = parent[n]:
return n
parent[n] = find(parent[n])
return parent[n]
def Union(a, b):
a = find(a)
b = find(b)
if a ! = b:
if a > b:
a, b = b, a
parent[b] = a
size[a] + = size[b]
def solve(s1, s2, s3):
for ch in range ( ord ( 'a' ), ord ( 'z' ) + 1 ):
make( chr (ch))
for i in range ( len (s1)):
Union(s1[i], s2[i])
new_s3 = ""
for i in range ( len (s3)):
new_s3 + = find(s3[i])
return new_s3
if __name__ = = "__main__" :
s1 = "abc"
s2 = "xcd"
s3 = "xdc"
print (solve(s1, s2, s3))
|
C#
using System;
class UnionFind
{
private int [] parent;
private int [] size;
public UnionFind( int n)
{
parent = new int [n];
size = new int [n];
for ( int i = 0; i < n; i++)
{
parent[i] = i;
size[i] = 1;
}
}
public int Find( int n)
{
if (n == parent[n])
return n;
return parent[n] = Find(parent[n]);
}
public void Union( int a, int b)
{
a = Find(a);
b = Find(b);
if (a != b)
{
if (a > b)
Swap( ref a, ref b);
parent[b] = a;
size[a] += size[b];
}
}
private static void Swap( ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
}
class Program
{
static string Solve( string s1, string s2, string s3)
{
int n = 26;
UnionFind uf = new UnionFind(n);
for ( int i = 0; i < s1.Length; i++)
{
uf.Union(s1[i] - 'a' , s2[i] - 'a' );
}
char [] result = new char [s3.Length];
for ( int i = 0; i < s3.Length; i++)
{
result[i] = ( char )( 'a' + uf.Find(s3[i] - 'a' ));
}
return new string (result);
}
static void Main()
{
string s1 = "abc" ;
string s2 = "xcd" ;
string s3 = "xdc" ;
string result = Solve(s1, s2, s3);
Console.WriteLine(result);
}
}
|
Javascript
const parent = {};
const size = {};
function make(n) {
parent[n] = n;
size[n] = 1;
}
function find(n) {
if (n === parent[n]) {
return n;
}
parent[n] = find(parent[n]);
return parent[n];
}
function Union(a, b) {
a = find(a);
b = find(b);
if (a !== b) {
if (a > b) {
[a, b] = [b, a];
}
parent[b] = a;
size[a] += size[b];
}
}
function solve(s1, s2, s3) {
for (let ch = 'a' .charCodeAt(0); ch <= 'z' .charCodeAt(0); ch++) {
make(String.fromCharCode(ch));
}
for (let i = 0; i < s1.length; i++) {
Union(s1.charAt(i), s2.charAt(i));
}
let new_s3 = "" ;
for (let i = 0; i < s3.length; i++) {
new_s3 += find(s3.charAt(i));
}
return new_s3;
}
const s1 = "abc" ;
const s2 = "xcd" ;
const s3 = "xdc" ;
console.log(solve(s1, s2, s3));
|
Time Complexity: O(N)
Auxiliary Space: O(1), because the number of nodes can never exceed 26 (number of alphabets).
Share your thoughts in the comments
Please Login to comment...