diff --git a/longest-substring-without-repeating-characters/hi-rachel.py b/longest-substring-without-repeating-characters/hi-rachel.py new file mode 100644 index 000000000..cdcb6aaf9 --- /dev/null +++ b/longest-substring-without-repeating-characters/hi-rachel.py @@ -0,0 +1,60 @@ +""" +문자열 s가 주어졌을 때, 중복된 문자를 제거하고 가장 긴 연속된 substring을 찾아라 + +1. 첫번째 풀이 + +Hint! +Generate all possible substrings & check for each substring if it's valid and keep updating maxLen accordingly. + +TC: O(N^3) +SC: O(N) +=> Time Limit Exceeded + +2. 최적화 - 슬라이딩 윈도우 + 해시셋 +- 슬라이딩 윈도우: 문자열 내에서 left, right 포인터로 범위를 정하고 점진적으로 이동 +- 해시셋: 현재 윈도우에 어떤 문자가 있는지 빠르게 체크 가능 +- 중복 문자가 등장하면 왼쪽 포인터를 이동시켜서 중복을 제거 + +TC: O(N) +SC: O(N) +""" + +# Time Limit Exceeded 풀이 +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + max_len = 0 + + # Generate all possible substrings without duplicate characters + def make_all_substrings(string): + nonlocal max_len + n = len(string) + for i in range(n): + for j in range(i + 1, n + 1): + k = len(string[i:j]) + if k == len(list(set(string[i:j]))): # if it's valid + max_len = max(k, max_len) # keep updating maxLen accordingly + + make_all_substrings(s) + return max_len + + +# 최적화 - 슬라이딩 윈도우 + 해시셋 풀이 +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + char_set = set() # 현재 윈도우에 있는 문자들 + left = 0 + max_len = 0 + + for right in range(len(s)): + # 중복 문자가 나오면 왼쪽 포인터를 이동시켜 중복 제거 + while s[right] in char_set: + char_set.remove(s[left]) + left += 1 + + # 중복이 없으면 윈도우에 추가 + char_set.add(s[right]) + + # 최대 길이 갱신 + max_len = max(max_len, right - left + 1) + + return max_len diff --git a/reverse-linked-list/hi-rachel.py b/reverse-linked-list/hi-rachel.py new file mode 100644 index 000000000..07d94f9c5 --- /dev/null +++ b/reverse-linked-list/hi-rachel.py @@ -0,0 +1,44 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next + +""" +1. Stack 활용 (LIFO) +- LinkedList의 모든 원소를 Stack에 넣고 꺼냄 +TC: O(n) time +SC: O(n) space + +2. 최적화 풀이 +- 현재 LinkedList를 거꾸로 뒤짚기 +TC: O(n) -> LinkedList를 딱 한 번 순회 +SC: O(1) -> 변수를 포인터 2개만 사용 +""" + +# Stack 풀이 +class Solution: + def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: + stack = [] + node = head + while node: + stack.append(node) + node= node.next + + dummy = ListNode(-1) + node = dummy + while stack: + node.next = stack.pop() + node = node.next + node.next = None + return dummy.next + +# 최적화 +class Solution: + def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: + prev, curr = None, head + while curr: + temp_next = curr.next + curr.next = prev + prev, curr = curr, temp_next + return prev