-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Expand file tree
/
Copy pathnext_greatest_letter.py
More file actions
90 lines (70 loc) · 2.62 KB
/
next_greatest_letter.py
File metadata and controls
90 lines (70 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
"""
Next Greatest Letter
Given a sorted list of lowercase letters and a target letter, find the
smallest letter in the list that is larger than the target. Letters wrap
around, so if the target is greater than or equal to the last letter the
answer is the first letter.
Reference: https://leetcode.com/problems/find-smallest-letter-greater-than-target/description/
Complexity:
next_greatest_letter -- O(log n) time, O(1) space (bisect)
next_greatest_letter_v1 -- O(log n) time, O(1) space (manual binary search)
next_greatest_letter_v2 -- O(n) time, O(1) space (brute force)
"""
from __future__ import annotations
import bisect
def next_greatest_letter(letters: list[str], target: str) -> str:
"""Find the smallest letter greater than *target* using ``bisect``.
Args:
letters: Sorted list of lowercase letters.
target: The letter to exceed.
Returns:
The smallest letter in *letters* that is strictly greater than
*target*, wrapping around if necessary.
Examples:
>>> next_greatest_letter(["c", "f", "j"], "a")
'c'
>>> next_greatest_letter(["c", "f", "j"], "c")
'f'
"""
index = bisect.bisect(letters, target)
return letters[index % len(letters)]
def next_greatest_letter_v1(letters: list[str], target: str) -> str:
"""Find the smallest letter greater than *target* using binary search.
Args:
letters: Sorted list of lowercase letters.
target: The letter to exceed.
Returns:
The smallest letter in *letters* that is strictly greater than
*target*, wrapping around if necessary.
Examples:
>>> next_greatest_letter_v1(["c", "f", "j"], "d")
'f'
"""
if letters[0] > target:
return letters[0]
if letters[len(letters) - 1] <= target:
return letters[0]
left, right = 0, len(letters) - 1
while left <= right:
mid = left + (right - left) // 2
if letters[mid] > target:
right = mid - 1
else:
left = mid + 1
return letters[left]
def next_greatest_letter_v2(letters: list[str], target: str) -> str:
"""Find the smallest letter greater than *target* using brute force.
Args:
letters: Sorted list of lowercase letters.
target: The letter to exceed.
Returns:
The smallest letter in *letters* that is strictly greater than
*target*, wrapping around if necessary.
Examples:
>>> next_greatest_letter_v2(["c", "f", "j"], "d")
'f'
"""
for letter in letters:
if letter > target:
return letter
return letters[0]