Convert characters of string1 to characters present in string2 by incrementing or decrementing lexicographically
Last Updated :
02 Feb, 2022
Given two strings A and B having lower case English alphabets, the task is to find the number of operations required to convert string A such that it only contains letters that are also in the string B where at each operation, the current character can be changed to either the next character or the previous character. Also, the next character after ‘z‘ is ‘a‘ and the previous character after ‘a‘ is ‘z‘.
Examples:
Input: A = “abcd”, B = “bc”
Output: 2
Explanation: The given string A = “abcd” can be converted into the string “bbcc” by incrementing the 1st character of the string in 1st move and decrementing the last character in 2nd move. Hence, A = “bbcc” has all the characters that are also in string B. Therefore, the required number of moves is 2 which is the minimum possible.
Input: A = “abcde”, B = “yg”
Output: 14
Approach: The given problem can be solved using a greedy approach. The idea is to convert all the characters in string A that are not in the string B into the nearest possible character that exists in string B which can be done by following the below steps:
- Store the frequency of characters of the string B in an unordered map m.
- Iterate through the given string A and check for each character in B, the number of steps required to convert the current character to it.
- The ways to convert a character x to y can be of two different types as follows:
- The 1st one is to increment the character x until y is reached i.e, clockwise rotation.
- The 2nd one is to decrement the character x until y is reached, i.e, anticlockwise rotation.
- Hence, maintain the sum of all the minimum of the moves in clockwise and anticlockwise rotations for each character in A, in a variable ans, which is the required value.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minOperations(string a, string b)
{
unordered_map< char , int > m;
for ( int i = 0; i < b.size(); i++) {
m[b[i]]++;
}
int ans = 0;
for ( int i = 0; i < a.size(); i++) {
int mn = INT_MAX;
for ( int j = 0; j < 26; j++) {
int val = a[i] - 'a' ;
if (m[a[i]] > 0) {
mn = 0;
break ;
}
else if (m[ 'a' + j] > 0) {
mn = min(mn, min( abs (val - j),
min((26 - val) + j,
val + (26 - j))));
}
}
ans += mn;
}
return ans;
}
int main()
{
string A = "abcde" ;
string B = "yg" ;
cout << minOperations(A, B);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int minOperations(String a, String b)
{
HashMap<Character,Integer> m = new HashMap<Character,Integer>();
for ( int i = 0 ; i < b.length(); i++) {
if (m.containsKey(b.charAt(i))){
m.put(b.charAt(i), m.get(b.charAt(i))+ 1 );
}
else {
m.put(b.charAt(i), 1 );
}
}
int ans = 0 ;
for ( int i = 0 ; i < a.length(); i++) {
int mn = Integer.MAX_VALUE;
for ( int j = 0 ; j < 26 ; j++) {
int val = a.charAt(i) - 'a' ;
if (m.containsKey(a.charAt(i))&&m.get(a.charAt(i)) > 0 ) {
mn = 0 ;
break ;
}
else if (m.containsKey(( char )( 'a' + j))&&m.get(( char )( 'a' + j)) > 0 ) {
mn = Math.min(mn, Math.min(Math.abs(val - j),
Math.min(( 26 - val) + j,
val + ( 26 - j))));
}
}
ans += mn;
}
return ans;
}
public static void main(String[] args)
{
String A = "abcde" ;
String B = "yg" ;
System.out.print(minOperations(A, B));
}
}
|
Python3
INT_MAX = 2147483647
def minOperations(a, b):
m = {}
for i in range ( 0 , len (b)):
if b[i] in m:
m[b[i]] + = 1
else :
m[b[i]] = 1
ans = 0
for i in range ( 0 , len (a)):
mn = INT_MAX
for j in range ( 0 , 26 ):
val = ord (a[i]) - ord ( 'a' )
if (a[i] in m and m[a[i]] > 0 ):
mn = 0
break
elif ( chr ( ord ( 'a' ) + j) in m and m[ chr ( ord ( 'a' ) + j)] > 0 ):
mn = min (mn, min ( abs (val - j),
min (( 26 - val) + j,
val + ( 26 - j))))
ans + = mn
return ans
if __name__ = = "__main__" :
A = "abcde"
B = "yg"
print (minOperations(A, B))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int MinOperations(String a, String b)
{
Dictionary< char , int > m = new Dictionary< char , int >();
for ( int i = 0; i < b.Length; i++)
{
if (m.ContainsKey(b[i]))
{
m[b[i]] += 1;
}
else
{
m[b[i]] = 1;
}
}
int ans = 0;
for ( int i = 0; i < a.Length; i++)
{
int mn = int .MaxValue;
for ( int j = 0; j < 26; j++)
{
int val = a[i] - 'a' ;
if (m.ContainsKey(a[i]) && m[a[i]] > 0)
{
mn = 0;
break ;
}
else if (m.ContainsKey(( char )( 'a' + j)) && m[( char )( 'a' + j)] > 0)
{
mn = Math.Min(mn, Math.Min(Math.Abs(val - j),
Math.Min((26 - val) + j,
val + (26 - j))));
}
}
ans += mn;
}
return ans;
}
public static void Main()
{
String A = "abcde" ;
String B = "yg" ;
Console.Write(MinOperations(A, B));
}
}
|
Javascript
<script>
function minOperations(a, b)
{
let m = new Map();
for (let i = 0; i < b.length; i++)
{
if (m.has(b[i])) {
m.set(b[i], m.get(b[i]) + 1);
}
else {
m.set(b[i], 1);
}
}
let ans = 0;
for (let i = 0; i< a.length; i++)
{
let mn = 999999;
for (let j = 0; j< 26; j++)
{
let val = a[i].charCodeAt(0) - 'a' .charCodeAt(0);
if (m.get(a[i]) > 0) {
mn = 0;
break ;
}
else if (m.has(String.fromCharCode( 'a' .charCodeAt(0) + j))
&& m.get(String.fromCharCode( 'a' .charCodeAt(0) + j)) > 0)
{
mn = Math.min(mn, Math.min(Math.abs(val - j),
Math.min((26 - val) + j,
val + (26 - j))));
}
}
ans += mn;
}
return ans;
}
let A = "abcde" ;
let B = "yg" ;
document.write(minOperations(A, B));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...