Skip to content

Commit e6ca811

Browse files
committed
Improved with precomputing
1 parent e20b9ee commit e6ca811

File tree

4 files changed

+27
-16
lines changed

4 files changed

+27
-16
lines changed
Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,33 @@
11
from typing import List
2+
from functools import lru_cache
23

34

4-
def find_longest_common_prefix(strings: List[str]):
5-
"""
6-
find_longest_common_prefix returns the longest string common at the start of any two strings in the passed list.
5+
def find_longest_common_prefix(strings: List[str]) -> str:
6+
if len(strings) < 2:
7+
return ""
8+
9+
# KEY INSIGHT: sort the strings. The longest common prefix between
10+
# any two strings must appear between two adjacent strings when sorted.
11+
# So we only need to check n-1 pairs instead of n² pairs.
12+
sorted_strings = sorted(strings)
713

8-
In the event that an empty list, a list containing one string, or a list of strings with no common prefixes is passed, the empty string will be returned.
9-
"""
1014
longest = ""
11-
for string_index, string in enumerate(strings):
12-
for other_string in strings[string_index+1:]:
13-
common = find_common_prefix(string, other_string)
14-
if len(common) > len(longest):
15-
longest = common
15+
for i in range(len(sorted_strings) - 1):
16+
common = cached_find_common_prefix(sorted_strings[i], sorted_strings[i + 1])
17+
if len(common) > len(longest):
18+
longest = common
19+
1620
return longest
1721

1822

19-
def find_common_prefix(left: str, right: str) -> str:
23+
@lru_cache(maxsize=None)
24+
def cached_find_common_prefix(left: str, right: str) -> str:
2025
min_length = min(len(left), len(right))
2126
for i in range(min_length):
2227
if left[i] != right[i]:
2328
return left[:i]
2429
return left[:min_length]
30+
31+
32+
def find_common_prefix(left: str, right: str) -> str:
33+
return cached_find_common_prefix(left, right)

Sprint-2/improve_with_precomputing/common_prefix/common_prefix_test.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import random
22
import string
33
import unittest
4-
54
from common_prefix import find_longest_common_prefix
65

76
class CommonPrefixTest(unittest.TestCase):

Sprint-2/improve_with_precomputing/count_letters/count_letters.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ def count_letters(s: str) -> int:
22
"""
33
count_letters returns the number of letters which only occur in upper case in the passed string.
44
"""
5+
# Precompute: build a set of all characters ONCE — lookups are now O(1)
6+
char_set = set(s)
7+
58
only_upper = set()
6-
for letter in s:
9+
for letter in char_set: # iterate unique chars only, not all 10M
710
if is_upper_case(letter):
8-
if letter.lower() not in s:
11+
if letter.lower() not in char_set: # O(1) lookup instead of O(n)
912
only_upper.add(letter)
13+
1014
return len(only_upper)
1115

1216

1317
def is_upper_case(letter: str) -> bool:
14-
return letter == letter.upper()
18+
return letter == letter.upper()

Sprint-2/improve_with_precomputing/count_letters/count_letters_test.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import random
22
import string
33
import unittest
4-
54
from count_letters import count_letters
65

76
class CommonPrefixTest(unittest.TestCase):

0 commit comments

Comments
 (0)