diff --git a/contains-duplicate/rara-record.py b/contains-duplicate/rara-record.py new file mode 100644 index 000000000..f83c4de2d --- /dev/null +++ b/contains-duplicate/rara-record.py @@ -0,0 +1,29 @@ +from typing import List + +""" +문제 설명: +- 배열에 중복된 값이 하나라도 있으면 True, 아니면 False를 반환하는 문제 + +목표 +- 배열을 순회하면서 각 값을 set에 추가 +- set은 중복을 허용하지 않으므로, 이미 set에 값이 있으면 중복이 발생한 것 +- 중복이 발견되면 true, 없으면 false 반환 + +시간복잡도: O(n) +- 배열을 한 번만 순회하므로 O(n) + +공간복잡도: O(n) +- set에 n개의 값이 저장됨 +""" + +class Solution: + def containsDuplicate(self, nums: List[int]) -> bool: + num_set = set() + for num in nums: + if num in num_set: + return True + else: + num_set.add(num) + return False + + diff --git a/longest-consecutive-sequence/rara-record.py b/longest-consecutive-sequence/rara-record.py new file mode 100644 index 000000000..31d563d2c --- /dev/null +++ b/longest-consecutive-sequence/rara-record.py @@ -0,0 +1,63 @@ +from typing import List + +""" +문제 설명: +정렬되지 않은 정수 배열에서 가장 긴 연속된 숫자 수열의 길이를 반환하는 문제 +O(n) 시간복잡도로 해결해야 함 => 정렬 x + +목표: +- 해시 세트로 중복 제거 +- 연속 수열의 시작점 찾기 + +[100,4,200,1,3,2] +- 해시 세트: {100, 4, 200, 1, 3, 2} +- 시작점 찾기: 1 (0이 없음), 100 (99가 없음), 200 (199가 없음) +- 1에서 시작: 1→2→3→4 (길이 4) +- 100에서 시작: 100만 (길이 1) +- 200에서 시작: 200만 (길이 1) +- 최대 길이: 4 + +- for num=1: 0이 없으므로 시작점 → while에서 1,2,3,4 처리 +- for num=2: 1이 있으므로 while 스킵 +- for num=3: 2가 있으므로 while 스킵 +- for num=4: 3이 있으므로 while 스킵 +→ 각 숫자가 while에서 1번만 +""" + +""" +시간복잡도: O(n) +- set(nums) 변환: O(n) +- 외부 for 루프: O(n)번 실행 +- while 총 실행 횟수: 전체 알고리즘에서 각 숫자가 while 안에서 최대 1번만 처리됨 + → 총 while 내부 작업 = n번 → O(n) +- 해시 조회: O(1) × 총 조회 횟수 +- 전체: O(n) + O(n) + O(n) = O(n) + +공간복잡도: O(n) +- num_set: 최대 n개의 서로 다른 숫자 저장 -> O(n) +- 기타 변수들: O(1) +- 전체: O(n) +""" + +class Solution: + def longestConsecutive(self, nums: List[int]) -> int: + num_set = set(nums) + max_length = 0 + + + for num in num_set: + + # 루프 안에서 한번만 처리 + if num - 1 not in num_set: + current_length = 1 + + while num + current_length in num_set: + current_length += 1 + + max_length = max(max_length, current_length) + + + return max_length + +print(Solution().longestConsecutive([100, 4, 200, 1, 3, 2])) + diff --git a/top-k-frequent-elements/rara-record.py b/top-k-frequent-elements/rara-record.py new file mode 100644 index 000000000..32908440b --- /dev/null +++ b/top-k-frequent-elements/rara-record.py @@ -0,0 +1,43 @@ +from typing import List +from heapq import nlargest + +""" +문제 설명: +이 문제는 주어진 k번째 만큼 빈도수가 높은 값들을 반환하는 문제 +빈도수 체크 후, 반환 값 순서는 상관 없다고 했으니 heap 사용 + +{ + 1: 3, # 1이 3번 등장 + 2: 2, # 2가 2번 등장 + 3: 1, # 3이 1번 등장 +} + +빈도수 기준으로 k번째만큼 큰 값을 반환 +""" + +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + count_dic = {} + + for num in nums: + if num in count_dic: + count_dic[num] += 1 + else: + count_dic[num] = 1 + + # 빈도수가 큰 순서대로 k개를 반환 + return nlargest(k, count_dic, key=count_dic.get) + +""" +시간복잡도: O(n log k) +- 딕셔너리 O(n) + heap을 사용해서 k번째 요소까지 반환 O(n log k) = O(n log k) + +공간복잡도: O(n) +- 최대 n개의 서로 다른 숫자가 있을 수 있고, O(n) +- heap은 최대 k개만 저장 -> O(k) +전체적으로 O(n) +""" + + + + diff --git a/two-sum/rara-record.py b/two-sum/rara-record.py new file mode 100644 index 000000000..bfe85b4d9 --- /dev/null +++ b/two-sum/rara-record.py @@ -0,0 +1,43 @@ +from typing import List + +""" +문제 설명: +nums에서 두 수를 더해 target이 되는 두 인덱스를 찾아 반환하는 문제 +같은 원소를 두 번 쓸 수 없음 +찾야야하는 값: taget - 현재 숫자 = 더해서 target이 되는 값 + +nums = [2,7,11,15], target = 9 +{ + 2: 0, (value: index) + 7: 1, + 11: 2, + 15: 3, +} + +1. nums를 한 번 순회하며 각 숫자와 인덱스를 딕셔너리에 저장 +2. 다시 nums를 순회하며, target - 현재 숫자가 딕셔너리에 있고 인덱스가 다르면 정답 쌍을 반환 +""" + + +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + dic = {} + + for key, value in enumerate(nums): + dic[value] = key + + # 다시 nums를 순회 + for key, value in enumerate(nums): + match = target - value + + # 같은 원소를 두번 쓸 수 없다. + if (match in dic) and key != dic[match]: + return [key, dic[match]] + +""" +시간 복잡도: O(n) +- 리스트를 두 번 순회하지만 각각 O(n)이 소요되므로, 총 시간 복잡도는 O(n) +공간 복잡도: O(n) +- 입력 크기가 n이라면 딕셔너리의 크기도 최대 n +""" +