Skip to content

Commit 365e87b

Browse files
committed
LeetCode 387. First Unique Character in a String
1 parent 8d02d36 commit 365e87b

File tree

2 files changed

+83
-3
lines changed

2 files changed

+83
-3
lines changed

README.md

+9-3
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,11 @@ Proposed solutions to some LeetCode problems. The first column links to the prob
116116
| [376. Wiggle Subsequence][lc376] | 🟠 Medium | [![python](res/py.png)](leetcode/wiggle-subsequence.py) |
117117
| [377. Combination Sum IV][lc377] | 🟠 Medium | [![python](res/py.png)][lc377py] |
118118
| [378. Kth Smallest Element in a Sorted Matrix][lc378] | 🟠 Medium | [![python](res/py.png)][lc378py] |
119-
| [392. Is Subsequence][lc392] | 🟢 Easy | [![python](res/py.png)](leetcode/is-subsequence.py) |
119+
| [387. First Unique Character in a String][lc387] | 🟢 Easy | [![python](res/py.png)][lc387py] |
120+
| [392. Is Subsequence][lc392] | 🟢 Easy | [![python](res/py.png)][lc392py] |
120121
| [394. Decode String][lc394] | 🟠 Medium | [![python](res/py.png)][lc394py] |
121-
| [406. Queue Reconstruction by Height][lc406] | 🟠 Medium | [![python](res/py.png)](leetcode/queue-reconstruction-by-height.py) |
122-
| [409. Longest Palindrome][lc409] | 🟢 Easy | [![python](res/py.png)](leetcode/longest-palindrome.py) |
122+
| [406. Queue Reconstruction by Height][lc406] | 🟠 Medium | [![python](res/py.png)][lc406py] |
123+
| [409. Longest Palindrome][lc409] | 🟢 Easy | [![python](res/py.png)][lc409py] |
123124
| [416. Partition Equal Subset Sum][lc416] | 🟠 Medium | [![python](res/py.png)][lc416py] |
124125
| [417. Pacific Atlantic Water Flow][lc417] | 🟢 Easy | [![python](res/py.png)][lc417py] |
125126
| [424. Longest Repeating Character Replacement][lc424] | 🟠 Medium | [![python](res/py.png)][lc424py] |
@@ -385,11 +386,16 @@ Proposed solutions to some LeetCode problems. The first column links to the prob
385386
[lc377py]: leetcode/combination-sum-iv.py
386387
[lc378]: https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/
387388
[lc378py]: leetcode/kth-smallest-element-in-a-sorted-matrix.py
389+
[lc387]: https://leetcode.com/problems/first-unique-character-in-a-string/
390+
[lc387py]: leetcode/first-unique-character-in-a-string.py
388391
[lc392]: https://leetcode.com/problems/is-subsequence/
392+
[lc392py]: leetcode/is-subsequence.py
389393
[lc394]: https://leetcode.com/problems/decode-string/
390394
[lc394py]: leetcode/decode-string.py
391395
[lc406]: https://leetcode.com/problems/queue-reconstruction-by-height/
396+
[lc406py]: leetcode/queue-reconstruction-by-height.py
392397
[lc409]: https://leetcode.com/problems/longest-palindrome/
398+
[lc409py]: leetcode/longest-palindrome.py
393399
[lc416]: https://leetcode.com/problems/partition-equal-subset-sum/
394400
[lc416py]: leetcode/partition-equal-subset-sum.py
395401
[lc417]: https://leetcode.com/problems/pacific-atlantic-water-flow/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# 387. First Unique Character in a String
2+
# 🟢 Easy
3+
#
4+
# https://leetcode.com/problems/first-unique-character-in-a-string/
5+
#
6+
# Tags: Hash Table - String - Queue - Counting
7+
8+
import timeit
9+
from collections import Counter
10+
11+
12+
# One pass to count character frequencies and one pass to find the
13+
# first character that is unique in the string.
14+
#
15+
# Time complexity: O(n) - Two passes == O(2n) => O(n).
16+
# Space complexity: O(1) - The counter has a max size of 26.
17+
#
18+
# Runtime: 160 ms, faster than 59.19%
19+
# Memory Usage: 14.1 MB, less than 59.01%
20+
class Solution:
21+
def firstUniqChar(self, s: str) -> int:
22+
# One pass to count the character frequencies.
23+
freq = Counter(s)
24+
# Second pass to return the index of the first character with
25+
# frequency == 1.
26+
for i, c in enumerate(s):
27+
if freq[c] == 1:
28+
return i
29+
# If no character had a frequency of 1, return -1
30+
return -1
31+
32+
33+
# This solution runs faster because the work is being done by C code
34+
# instead of a Python loop. If the code performing the work was both C
35+
# or Python, it should be slower than the previous one.
36+
#
37+
# Time complexity: O(n)
38+
# Space complexity: O(1) - For the set, max of 26 characters.
39+
#
40+
# Runtime: 70 ms, faster than 98.50%
41+
# Memory Usage: 14.1 MB, less than 59.01%
42+
class ListComprehension:
43+
def firstUniqChar(self, s: str) -> int:
44+
return min(
45+
[s.index(char) for char in set(s) if s.count(char) == 1] or [-1]
46+
)
47+
48+
49+
def test():
50+
executors = [Solution]
51+
tests = [
52+
["leetcode", 0],
53+
["loveleetcode", 2],
54+
["aabb", -1],
55+
]
56+
for executor in executors:
57+
start = timeit.default_timer()
58+
for _ in range(1):
59+
for n, t in enumerate(tests):
60+
sol = executor()
61+
result = sol.firstUniqChar(t[0])
62+
exp = t[1]
63+
assert result == exp, (
64+
f"\033[93m» {result} <> {exp}\033[91m for "
65+
+ f"test {n} using \033[1m{executor.__name__}"
66+
)
67+
stop = timeit.default_timer()
68+
used = str(round(stop - start, 5))
69+
cols = "{0:20}{1:10}{2:10}"
70+
res = cols.format(executor.__name__, used, "seconds")
71+
print(f"\033[92m» {res}\033[0m")
72+
73+
74+
test()

0 commit comments

Comments
 (0)