|
| 1 | +from unittest import TestCase, main |
| 2 | + |
| 3 | + |
| 4 | +class Solution: |
| 5 | + def lengthOfLongestSubstring(self, s: str) -> int: |
| 6 | + return self.solve_sliding_window(s) |
| 7 | + |
| 8 | + """ |
| 9 | + Runtime: 313 ms (Beats 8.97%) |
| 10 | + Time Complexity: |
| 11 | + - left가 0에서 len(s)까지 조회, right가 left + 1 부터 len(s)까지 조회하므로 O(n * (n + 1) / 2) |
| 12 | + - left가 조회할 때마다, 2항 max 연산하므로 * 2 |
| 13 | + > O((n * (n + 1) / 2) * 2) ~= O(n ^ 2) |
| 14 | +
|
| 15 | + Memory: 16.51 (Beats 81.63%) |
| 16 | + Space Complexity: O(n) |
| 17 | + > checker가 최대 s의 길이만큼 커질 수 있으므로 O(n), upper bound |
| 18 | + """ |
| 19 | + def solve_two_pointer(self, s: str) -> int: |
| 20 | + if not s: |
| 21 | + return 0 |
| 22 | + |
| 23 | + max_length = 1 |
| 24 | + for left in range(len(s)): |
| 25 | + if len(s) - left + 1 < max_length: |
| 26 | + return max_length |
| 27 | + |
| 28 | + right = left + 1 |
| 29 | + checker = set(s[left]) |
| 30 | + while right < len(s): |
| 31 | + if s[right] in checker: |
| 32 | + break |
| 33 | + |
| 34 | + checker.add(s[right]) |
| 35 | + right += 1 |
| 36 | + |
| 37 | + max_length = max(max_length, len(checker)) |
| 38 | + |
| 39 | + return max_length |
| 40 | + |
| 41 | + """ |
| 42 | + Runtime: 58 ms (Beats 46.47%) |
| 43 | + Time Complexity: |
| 44 | + - 중복 검사는 set을 사용하므로 O(1) |
| 45 | + - right가 len(s)까지 조회하므로 O(n) |
| 46 | + - right가 조회한 뒤 2항 max 연산하는데 O(2) |
| 47 | + - left가 최대 right까지 조회하고 right < len(s) 이므로 O(n), upper bound |
| 48 | + > O(n) * O(2) + O(n) ~= O(n) |
| 49 | +
|
| 50 | + Memory: 16.60 (Beats 41.73%) |
| 51 | + Space Complexity: O(n) |
| 52 | + > checker가 최대 s의 길이만큼 커질 수 있으므로 O(n), upper bound |
| 53 | + """ |
| 54 | + def solve_sliding_window(self, s: str) -> int: |
| 55 | + max_length = 0 |
| 56 | + left = right = 0 |
| 57 | + checker = set() |
| 58 | + while left < len(s) and right < len(s): |
| 59 | + while right < len(s) and s[right] not in checker: |
| 60 | + checker.add(s[right]) |
| 61 | + right += 1 |
| 62 | + |
| 63 | + max_length = max(max_length, len(checker)) |
| 64 | + |
| 65 | + while left < len(s) and (right < len(s) and s[right] in checker): |
| 66 | + checker.remove(s[left]) |
| 67 | + left += 1 |
| 68 | + |
| 69 | + return max_length |
| 70 | + |
| 71 | + |
| 72 | +class _LeetCodeTestCases(TestCase): |
| 73 | + def test_1(self): |
| 74 | + s = "pwwkew" |
| 75 | + output = 3 |
| 76 | + self.assertEqual(Solution.lengthOfLongestSubstring(Solution(), s), output) |
| 77 | + |
| 78 | + |
| 79 | +if __name__ == '__main__': |
| 80 | + main() |
0 commit comments