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 check whether one string can be 1-to-1 mapped into another string in Python
Sometimes we need to check whether one string can be mapped to another string with a 1-to-1 character mapping. This means each character in the first string maps to exactly one character in the second string, and vice versa.
For example, if we have strings "papa" and "lili", we can create a valid mapping: "p" ? "l" and "a" ? "i". The character order remains unchanged.
Algorithm
To solve this problem, we use two dictionaries to track mappings in both directions ?
- Create two dictionaries: one for mapping characters from string
stot, another for reverse mapping - Iterate through both strings simultaneously
- For each character pair, check if existing mappings conflict
- If no conflicts, establish new mappings
- Return
Trueif all characters can be mapped consistently
Implementation
def can_map_strings(s, t):
# Check if strings have different lengths
if len(s) != len(t):
return False
s_dict = {} # Maps characters from s to t
t_dict = {} # Maps characters from t to s
for i in range(len(s)):
char_s = s[i]
char_t = t[i]
# Check if s[i] already has a mapping
if char_s in s_dict:
if s_dict[char_s] != char_t:
return False
# Check if t[i] already has a mapping
elif char_t in t_dict:
if t_dict[char_t] != char_s:
return False
# Create new mappings
else:
s_dict[char_s] = char_t
t_dict[char_t] = char_s
return True
# Test the function
print(can_map_strings("papa", "lili"))
print(can_map_strings("abc", "def"))
print(can_map_strings("aab", "xyz"))
True True False
How It Works
Let's trace through the example "papa" and "lili" ?
def trace_mapping(s, t):
s_dict = {}
t_dict = {}
print(f"Mapping '{s}' to '{t}':")
for i in range(len(s)):
char_s = s[i]
char_t = t[i]
print(f"Step {i+1}: '{char_s}' -> '{char_t}'")
if char_s in s_dict:
if s_dict[char_s] != char_t:
print(f"Conflict! '{char_s}' already maps to '{s_dict[char_s]}'")
return False
elif char_t in t_dict:
if t_dict[char_t] != char_s:
print(f"Conflict! '{char_t}' already maps to '{t_dict[char_t]}'")
return False
else:
s_dict[char_s] = char_t
t_dict[char_t] = char_s
print(f"New mapping: '{char_s}' -> '{char_t}'")
print(f"Current mappings: {s_dict}")
return True
trace_mapping("papa", "lili")
Mapping 'papa' to 'lili':
Step 1: 'p' -> 'l'
New mapping: 'p' -> 'l'
Current mappings: {'p': 'l'}
Step 2: 'a' -> 'i'
New mapping: 'a' -> 'i'
Current mappings: {'p': 'l', 'a': 'i'}
Step 3: 'p' -> 'l'
Current mappings: {'p': 'l', 'a': 'i'}
Step 4: 'a' -> 'i'
Current mappings: {'p': 'l', 'a': 'i'}
Edge Cases
# Test various edge cases
test_cases = [
("", ""), # Empty strings
("a", "b"), # Single characters
("aa", "ab"), # One-to-many mapping (invalid)
("ab", "aa"), # Many-to-one mapping (invalid)
("abc", "abc"), # Identity mapping
]
for s, t in test_cases:
result = can_map_strings(s, t)
print(f"'{s}' -> '{t}': {result}")
'' -> '': True 'a' -> 'b': True 'aa' -> 'ab': False 'ab' -> 'aa': False 'abc' -> 'abc': True
Time and Space Complexity
- Time Complexity: O(n), where n is the length of the strings
- Space Complexity: O(k), where k is the number of unique characters
Conclusion
Use two dictionaries to track bidirectional character mappings. This ensures each character has exactly one mapping in both directions, maintaining the 1-to-1 relationship required for valid string transformation.
