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 there is any pair of words which are almost same in Python
Suppose we have a list of lowercase strings called words where each word is of same length. We have to check whether there are two strings that differ only in one character.
So, if the input is like words = ["seed", "pick", "lick", "root", "live"], then the output will be True, as "pick" and "lick" are almost same.
Algorithm
To solve this, we will follow these steps ?
- Create a new set to store patterns
- For each word in words, do
- For each index i in word, do
- Create a pattern by replacing character at index i with "*"
- If this pattern already exists in set, return True
- Otherwise, add the pattern to set
- For each index i in word, do
- Return False if no matching pattern found
How It Works
The algorithm creates patterns for each word by replacing one character at a time with "*". If two words differ by only one character, they will generate the same pattern. For example, "pick" and "lick" both generate the pattern "*ick" when the first character is replaced.
Example
Let us see the following implementation to get better understanding ?
def solve(words):
s = set()
for word in words:
for i, w in enumerate(word):
pattern = word[:i] + "*" + word[i + 1:]
if pattern in s:
return True
else:
s.add(pattern)
return False
words = ["seed", "pick", "lick", "root", "live"]
print(solve(words))
The output of the above code is ?
True
Step-by-Step Execution
Let's trace through the algorithm with our example ?
def solve_with_trace(words):
s = set()
for word in words:
print(f"Processing word: {word}")
for i in range(len(word)):
pattern = word[:i] + "*" + word[i + 1:]
print(f" Pattern: {pattern}")
if pattern in s:
print(f" Found match! Pattern {pattern} already exists")
return True
else:
s.add(pattern)
print(f" Patterns so far: {sorted(s)}")
print()
return False
words = ["seed", "pick", "lick", "root", "live"]
result = solve_with_trace(words)
print(f"Final result: {result}")
Processing word: seed Pattern: *eed Pattern: s*ed Pattern: se*d Pattern: see* Patterns so far: ['*eed', 's*ed', 'se*d', 'see*'] Processing word: pick Pattern: *ick Pattern: p*ck Pattern: pi*k Pattern: pic* Patterns so far: ['*eed', '*ick', 'p*ck', 'pi*k', 'pic*', 's*ed', 'se*d', 'see*'] Processing word: lick Pattern: *ick Found match! Pattern *ick already exists Final result: True
Alternative Approach
You can also solve this using a nested loop to compare each pair of words directly ?
def solve_direct(words):
n = len(words)
for i in range(n):
for j in range(i + 1, n):
diff_count = sum(1 for a, b in zip(words[i], words[j]) if a != b)
if diff_count == 1:
print(f"Found almost same words: {words[i]} and {words[j]}")
return True
return False
words = ["seed", "pick", "lick", "root", "live"]
print(solve_direct(words))
Found almost same words: pick and lick True
Comparison
| Approach | Time Complexity | Space Complexity | Best For |
|---|---|---|---|
| Pattern Matching | O(n * m) | O(n * m) | Large number of words |
| Direct Comparison | O(n² * m) | O(1) | Small number of words |
Where n is the number of words and m is the length of each word.
Conclusion
The pattern matching approach is more efficient for large datasets as it uses a set to store patterns and finds matches in O(n * m) time. The direct comparison approach is simpler to understand but has higher time complexity of O(n² * m).
