Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find minimum swaps required to make given anagram in python
Suppose we have two strings S and T and they are anagrams of each other. We have to find the minimum number of swaps required in S to make it same as T.
So, if the input is like S = "kolkata" T = "katloka", then the output will be 3, as we can swap in this sequence: [katloka (given), kotlaka, koltaka, kolkata].
Algorithm
To solve this, we will follow these steps ?
- Define a function util(). This will take S, T, i
- if i >= size of S, then
- return 0
- if S[i] is same as T[i], then
- return util(S, T, i + 1)
- x := T[i]
- ret := 99999
- for j in range i + 1 to size of T, do
- if x is same as S[j], then
- swap S[i] and S[j]
- ret := minimum of ret and (1 + util(S, T, i + 1))
- swap S[i] and S[j]
- if x is same as S[j], then
- return ret
- From the main method, return util(S, T, 0)
Example
Let us see the following implementation to get better understanding ?
class Solution:
def util(self, S, T, i):
S = list(S)
T = list(T)
if i >= len(S):
return 0
if S[i] == T[i]:
return self.util(S, T, i + 1)
x = T[i]
ret = 99999
for j in range(i + 1, len(T)):
if x == S[j]:
S[i], S[j] = S[j], S[i]
ret = min(ret, 1 + self.util(S, T, i + 1))
S[i], S[j] = S[j], S[i]
return ret
def solve(self, S, T):
return self.util(S, T, 0)
ob = Solution()
S = "kolkata"
T = "katloka"
print(ob.solve(S, T))
3
How It Works
The algorithm uses recursive backtracking:
- Base case: If we've processed all characters (i >= len(S)), return 0 swaps
- Match case: If characters at position i are already equal, move to next position
- Swap case: Find all possible characters in remaining string that match target character, try swapping each one, and take the minimum swaps needed
Alternative Optimized Approach
For better performance, we can use a cycle-based approach ?
def min_swaps_optimized(s, t):
if len(s) != len(t) or sorted(s) != sorted(t):
return -1 # Not anagrams
s, t = list(s), list(t)
swaps = 0
for i in range(len(s)):
if s[i] != t[i]:
# Find the character we need in the remaining part
for j in range(i + 1, len(s)):
if s[j] == t[i]:
# Swap to correct position
s[i], s[j] = s[j], s[i]
swaps += 1
break
return swaps
# Test the optimized approach
S = "kolkata"
T = "katloka"
result = min_swaps_optimized(S, T)
print(f"Minimum swaps needed: {result}")
Minimum swaps needed: 3
Conclusion
The recursive backtracking approach finds the minimum swaps by exploring all possibilities. The optimized greedy approach is more efficient for practical use, achieving the same result with O(n²) time complexity.
