Skip to content

Commit 4f308e2

Browse files
committed
one away soln update
1 parent 93f8549 commit 4f308e2

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

Python/chapter01/1.5 - OneAway/miguel_1.5_sol.py

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
if they are one edit (or zero edits) away.
77
"""
88
import unittest
9-
import collections
109
from typing import Callable
1110

1211

@@ -18,27 +17,43 @@ def one_away(s1: str, s2: str) -> bool:
1817
2. remove a character
1918
3. replace a character
2019
Zero edits away means the two strings are exactly the same.
21-
We will analyze character frequencies to detect anomalies.
22-
An anomaly can be any of the 3 types of edits.
23-
Runtime: O(n + m), where n is length of s1 and m is length of s2
24-
Space Complexity: O(n + m)
20+
We will do different checks depending on the size different of the strings.
21+
Runtime: O(n), where n is length of s1
22+
Space Complexity: O(n + n +/- 1) = O(n), where n is length of s1
2523
:param s1: one string we want to compare
2624
:param s2: other string to compare
2725
:return: true if one or zero edits away, false otherwise
2826
"""
29-
# if size differs by more than 1, guaranteed more than one anomaly.
27+
# if size differs by more than 1, guaranteed more than one edit distance.
3028
if abs(len(s1) - len(s2)) > 1:
3129
return False
30+
# if size is the same, scan for edits
31+
if len(s1) == len(s2):
32+
edits = 0
33+
for i, c in enumerate(s1):
34+
if c == s2[i]:
35+
continue
36+
edits += 1
37+
if edits > 1:
38+
return False
39+
return True
40+
# otherwise, we have an insertion/deletion
41+
# compare both strings for insertion/deletion
42+
# want to loop through the shorter string to avoid going out of bounds
43+
s_short = s1 if len(s1) < len(s2) else s2
44+
s_long = s1 if len(s1) > len(s2) else s2
3245

33-
char_freqs_s1 = collections.Counter(s1)
34-
char_freqs_s2 = collections.Counter(s2)
35-
36-
anomalies = 0
37-
for key, value in char_freqs_s1.items():
38-
if key not in char_freqs_s2 or value != char_freqs_s2[key]:
39-
anomalies += 1
40-
if anomalies > 1:
41-
return False
46+
addend = 0
47+
for i, c in enumerate(s_short):
48+
if c == s_long[i + addend]:
49+
continue
50+
if i == i + addend:
51+
# addend is 0, will check next char in next iteration
52+
addend += 1
53+
continue
54+
# otherwise, addend is not 0, and we did not match characters.
55+
# guaranteed at least 2 edit distance
56+
return False
4257
return True
4358

4459

@@ -56,6 +71,8 @@ def _run_tests(self, f: Callable[[str, str], bool]) -> None:
5671
("a", "b", True),
5772
("", "", True),
5873
("pale", "elap", False),
74+
("pale", "elaps", False),
75+
("pale", "palse", True)
5976
]
6077
for s1, s2, expected in cases:
6178
self.assertEqual(f(s1, s2), expected, msg=(s1, s2))

0 commit comments

Comments
 (0)