This article describes the question from Day 9 of the 30 Days of Code competition hosted by Geeks for Geeks.
Question
Professor McGonagall teaches transfiguration at Hogwarts. She has given Harry the task of changing himself into a cat. She explains that the trick is to analyze your own DNA and change it into the DNA of a cat. The transfigure spell can be used to pick any one character from the DNA string, remove it and insert it in the beginning. Help Harry calculates minimum number of times he needs to use the spell to change himself into a cat.
Example 1:
Input: A = "GEEKSFORGEEKS" B = "FORGEEKSGEEKS" Output: 3 Explanation:The conversion can take place in 3 operations:
- Pick 'R' and place it at the front, A="RGEEKSFOGEEKS"
- Pick 'O' and place it at the front, A="ORGEEKSFGEEKS"
- Pick 'F' and place it at the front, A="FORGEEKSGEEKS"
Example 2:
Input: A = "ABC" B = "BCA" Output: 2 Explanation: The conversion can take place in 2 operations:
- Pick 'C' and place it at the front, A = "CAB"
- Pick 'B' and place it at the front, A = "BCA"
Your Task:
You don't need to read input or print anything. Complete the function transfigure() which takes strings A and B as input parameters and returns the minimum number of spells needed. If it is not possible to convert A to B then return -1.
Expected Time Complexity: O(max(|A|, |B|)) Expected Auxiliary Space: O(1)
Constraints: 1 ≤ |A|, |B| ≤ 105 A and B consists of lowercase and uppercase letters of english alphabet only.
Solution
Here is the solution.
class Solution:
def transfigure(self, a, b):
if (len(a) != len(b)):
return -1
i,j,s = 0,0,0
c = [0] * 128
for i in range(len(a)):
c[ord(a[i])] += 1
c[ord(b[i])] -= 1
for i in range(len(c)):
if c[i] != 0:
return -1
i = len(a) - 1
j = i
while i >= 0:
if a[i] != b[j]:
s += 1
else:
j -= 1
i -= 1
return s
If the two strings are different lengths, it is impossible to transfigure one into the other. Since there will be excess characters in either A
or B
.
We store pointers i
and j
, these are our positions to check in the first string A
, and second string B
. We store the number of insertions s
. The scope of the question regards only the English alphabet (i.e, A-Z and a-z). With the following functions, ord('A')
and ord('z')
, we find that range of our possible characters is from 0 to 127, with 128 characters possible in total (computers start counting at 0).
The first loop in this algorithm checks that each character has the same frequency in string A
and string B
. If there are more of one character in one string, but not the other, it is impossible to perform a transfiguration. We make this check and the length check above, before evaluating the sum, to avoid an infinite loop in our while loop further down.
Now in the loop, we start from the end of both strings (i.e, i
and j
are both len(A)
, which equals len(B)
). We compare these two characters from each string, if they are not the same, an insertion must be made, so we increase the sum. i
is decreased, but j
is not, so we compare the next character. In the case that they both match, we decrease j
, and i
is decreased anyway, as we subtract 1 each iteration of the loop regardless. Now we compare the next two positions. So on and so forth.
The loop stops once i
is no longer larger than 0. In other words, we have reached the start of the string. There are no more character indexes to compare at this point. s
has accumulated the total number of insertions we would have to perform. We return that s
once the loop has been completed.