|
1 | 1 | from typing import List |
2 | 2 |
|
3 | | - |
4 | | -def find_longest_common_prefix(strings: List[str]): |
| 3 | +def find_longest_common_prefix(strings: List[str]) -> str: |
5 | 4 | """ |
6 | | - find_longest_common_prefix returns the longest string common at the start of any two strings in the passed list. |
7 | | -
|
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. |
| 5 | + Returns the longest string common at the start of any two strings in the list. |
9 | 6 | """ |
| 7 | + if len(strings) < 2: |
| 8 | + return "" |
| 9 | + |
| 10 | + # Precompute the set of prefixes for each string |
| 11 | + prefixes = {} |
| 12 | + for s in strings: |
| 13 | + prefixes[s] = [s[:i] for i in range(1, len(s) + 1)] |
| 14 | + |
10 | 15 | 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) |
| 16 | + n = len(strings) |
| 17 | + for i in range(n): |
| 18 | + for j in range(i + 1, n): |
| 19 | + # Compare prefixes of strings[i] and strings[j] efficiently |
| 20 | + common = _common_prefix_precomputed(prefixes[strings[i]], strings[j]) |
14 | 21 | if len(common) > len(longest): |
15 | 22 | longest = common |
16 | | - return longest |
17 | 23 |
|
| 24 | + return longest |
18 | 25 |
|
19 | | -def find_common_prefix(left: str, right: str) -> str: |
20 | | - min_length = min(len(left), len(right)) |
21 | | - for i in range(min_length): |
22 | | - if left[i] != right[i]: |
23 | | - return left[:i] |
24 | | - return left[:min_length] |
| 26 | +def _common_prefix_precomputed(prefix_list: List[str], other: str) -> str: |
| 27 | + # Find the longest prefix of other that exists in prefix_list |
| 28 | + for prefix in reversed(prefix_list): |
| 29 | + if other.startswith(prefix): |
| 30 | + return prefix |
| 31 | + return "" |
0 commit comments