From 269536abcc8b40d9e4da6172c94b065370547674 Mon Sep 17 00:00:00 2001 From: Seoya0512 Date: Wed, 12 Nov 2025 18:08:03 +0900 Subject: [PATCH 1/6] feat: week1-contains duplicate --- contains-duplicate/Seoya0512.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 contains-duplicate/Seoya0512.py diff --git a/contains-duplicate/Seoya0512.py b/contains-duplicate/Seoya0512.py new file mode 100644 index 0000000000..6ced191997 --- /dev/null +++ b/contains-duplicate/Seoya0512.py @@ -0,0 +1,23 @@ +''' +Approach: + 주어진 배열에서 중복된 요소가 존재하는지 확인하는 문제입니다. + 해시 테이블 자료구조인 set을 이용해 nums의 모든 요소를 순회하며 중복을 제거한 객체를 생성했습니다. + 이후 set의 길이와 원본 배열의 길이를 비교하여, 길이가 다르다면 중복된 요소가 존재함을 의미합니다. + +Time Complexity: + O(n) + - set(nums)를 생성할 때 nums의 모든 원소를 한 번씩 순회하며 해시 테이블에 삽입하기 때문입니다. + +Space Complexity: + O(n) + - 중복을 제거한 원소들이 새로운 집합(set)에 저장되므로, + 최대 nums의 크기만큼 추가 공간이 필요합니다. +''' + +class Solution: + def containsDuplicate(self, nums: List[int]) -> bool: + if len(nums) != len(set(nums)): + return True + else: + return False + \ No newline at end of file From bd23824154528b1cd6589d567512a39bda70be03 Mon Sep 17 00:00:00 2001 From: Seoya0512 Date: Wed, 12 Nov 2025 23:25:34 +0900 Subject: [PATCH 2/6] feat: week1-two sum --- two-sum/Seoya0512.py | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 two-sum/Seoya0512.py diff --git a/two-sum/Seoya0512.py b/two-sum/Seoya0512.py new file mode 100644 index 0000000000..1ba5d229e0 --- /dev/null +++ b/two-sum/Seoya0512.py @@ -0,0 +1,49 @@ +''' +Approach: + 주어진 배열을 두 번 순회하며 모든 가능한 쌍을 검사합니다. + 각 원소에 대해 이후의 원소들과의 합이 target과 같은지 비교하여 일치하는 경우 인덱스를 반환합니다. + +Time Complexity: + O(n²) + - Outer Loop에서 n번 반복 + - Inner Loop에서 각 idx마다 최소 n-1번 반복 + +Space Complexity: + O(1) + - 결과를 저장하기 위해 상수 값을 필요로 하지만, 입력값의 크키에 비례한 새로운 공간 불요 +''' + +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + for idx, xnum in enumerate(nums): + for jdx in range(idx + 1, len(nums)): + if (xnum + nums[jdx]) == target: + return [idx, jdx] + return [] + +''' +(개선) +Approach: + “You may assume that each input would have exactly one solution, and you may not use the same element twice.” + 라는 문구에서 항상 정답이 존재하며 같은 원소를 중복 사용할 수 없음을 알 수 있습니다. + 이를 바탕으로 각 원소 num에 대해 (target - num)이 이전에 등장한 적이 있는지를 해시맵을 이용해 빠르게 확인하도록 개선했습니다. + 즉, 중복이 없고 답이 반드시 존재한다는 조건 아래에서, inner loop 없이 바로 찾기 위해 딕셔너리를 사용하 것입니다. + +Time Complexity: + O(n) + - 리스트를 한 번 순회하면서 딕셔너리를 채워 넣는 데 걸리는 전체 시간 + +Space Complexity: + O(n) + - 해시맵에 key-value 쌍으로 저장되는 공간 +''' +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + hash_map = {} + for i, num in enumerate(nums): + diff = target - num + if diff in hash_map: + return [hash_map[diff], i] + hash_map[num] = i + + \ No newline at end of file From f002107ec84cafdba5cda2d277f29577a2d60875 Mon Sep 17 00:00:00 2001 From: Seoya0512 Date: Thu, 13 Nov 2025 00:02:07 +0900 Subject: [PATCH 3/6] feat: week1-remove space --- contains-duplicate/Seoya0512.py | 2 -- two-sum/Seoya0512.py | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/contains-duplicate/Seoya0512.py b/contains-duplicate/Seoya0512.py index 6ced191997..bdcd097888 100644 --- a/contains-duplicate/Seoya0512.py +++ b/contains-duplicate/Seoya0512.py @@ -13,11 +13,9 @@ - 중복을 제거한 원소들이 새로운 집합(set)에 저장되므로, 최대 nums의 크기만큼 추가 공간이 필요합니다. ''' - class Solution: def containsDuplicate(self, nums: List[int]) -> bool: if len(nums) != len(set(nums)): return True else: return False - \ No newline at end of file diff --git a/two-sum/Seoya0512.py b/two-sum/Seoya0512.py index 1ba5d229e0..1a4cc05991 100644 --- a/two-sum/Seoya0512.py +++ b/two-sum/Seoya0512.py @@ -20,7 +20,7 @@ def twoSum(self, nums: List[int], target: int) -> List[int]: if (xnum + nums[jdx]) == target: return [idx, jdx] return [] - + ''' (개선) Approach: @@ -45,5 +45,3 @@ def twoSum(self, nums: List[int], target: int) -> List[int]: if diff in hash_map: return [hash_map[diff], i] hash_map[num] = i - - \ No newline at end of file From c991a2dfb9ed2bf13648c47df8c76690cd2217ac Mon Sep 17 00:00:00 2001 From: Seoya0512 Date: Thu, 13 Nov 2025 15:48:43 +0900 Subject: [PATCH 4/6] feat: week1-top k frequent elements --- top-k-frequent-elements/Seoya0512.py | 88 ++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 top-k-frequent-elements/Seoya0512.py diff --git a/top-k-frequent-elements/Seoya0512.py b/top-k-frequent-elements/Seoya0512.py new file mode 100644 index 0000000000..38fd24c591 --- /dev/null +++ b/top-k-frequent-elements/Seoya0512.py @@ -0,0 +1,88 @@ +from typing import List + +''' +[1차 시도] +Approach: nums 리스트의 각 원소의 빈도수를 hash_map에 저장후, 빈도수 기준으로 정렬을 하고 상위 k개를 반환 +count 함수를 사용해서 간견할게 코드를 완성하고자 했습니다. + +Time Complexity: O(n²) +- for num in nums 순환과 nums.count(num) 의 중첩으로 인해 O(n²) 발생 + +Space Complexity: O(n) +- hash_map 저장 공간과 sorted_hash_map 저장 공간으로 인해 O(n) 발생 + +- +''' +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + hash_map = {} + for num in nums: + hash_map[num] = nums.count(num) + + # hash_map 정렬 + sorted_hash_map = sorted(hash_map.items(), key=lambda x: x[1], reverse=True) + # 상위 k개 반환 + return [x[0] for x in sorted_hash_map[:k]] + +''' +[2차 시도] +Approach: 위의 방식에서 count 함수를 제거하고, hash_map에 빈도수를 직접 카운팅 하도록 수정하도록 해서 +Time Complexity를 개선하기 위해 노력했습니다. + +Time Complexity: O(n log n) +- for num in nums 순환에 O(n) 발생 +- hash_map 정렬에 O(m log m)으로 예측 되며 최대 m =< n 이므로 O(n log n) 발생 + +''' +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + hash_map = {} + for num in nums: + if hash_map.get(num): + hash_map.update({num: hash_map[num]+1}) + else: + hash_map.update({num: 1}) + + # hash_map 정렬 + sorted_hash_map = sorted(hash_map.items(), key=lambda x: x[1], reverse=True) + # 상위 k개 반환 + return [x[0] for x in sorted_hash_map[:k]] + + +''' +[3차 시도 - Bucket Sort 활용] +Approach: Bucket Sort 방식을 활용할 수 있다는 것을 알게 됐습니다. +for loop와 조건문이 반복되기도 하지만, 배열의 크기에 맞춰 한번씩만 순회하기 때문에 +Time Complexity를 O(n)으로 개선할 수 있었습니다. + +Time Complexity: O(n) +- for num in nums 순환하며 빈도수 카운팅: O(n) +- 빈도에 따라 숫자들을 버킷에 넣기: O(n) +- 버킷을 뒤에서부터 순회하며 상위 k개 숫자 채우기: O(n) + +Space Complexity: O(n) +- freq 딕셔너리와 bucket 리스트로 인해 O(n) 발생 +''' +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + hash_map = {} + for num in nums: + hash_map[num] = hash_map.get(num, 0) + 1 + + # 인덱스 = 등장 횟수, 값 = 그 횟수만큼 등장한 숫자 리스트 + bucket = [[] for _ in range(len(nums) + 1)] + for num, count in hash_map.items(): + bucket[count].append(num) + + result: List[int] = [] + # 가장 큰 빈도부터 내려오면서 숫자 수집 (for 루프 역순) + for count in range(len(bucket) - 1, -1, -1): + if not bucket[count]: + continue + + for num in bucket[count]: + result.append(num) + if len(result) == k: + return result + + return result From a38015656d4612a2a9c498575f5c8da28827fcee Mon Sep 17 00:00:00 2001 From: Seoya0512 Date: Sat, 15 Nov 2025 14:17:05 +0900 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- top-k-frequent-elements/Seoya0512.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/top-k-frequent-elements/Seoya0512.py b/top-k-frequent-elements/Seoya0512.py index 38fd24c591..9771fc294d 100644 --- a/top-k-frequent-elements/Seoya0512.py +++ b/top-k-frequent-elements/Seoya0512.py @@ -61,7 +61,7 @@ def topKFrequent(self, nums: List[int], k: int) -> List[int]: - 버킷을 뒤에서부터 순회하며 상위 k개 숫자 채우기: O(n) Space Complexity: O(n) -- freq 딕셔너리와 bucket 리스트로 인해 O(n) 발생 +- hash_map 딕셔너리와 bucket 리스트로 인해 O(n) 발생 ''' class Solution: def topKFrequent(self, nums: List[int], k: int) -> List[int]: @@ -69,7 +69,7 @@ def topKFrequent(self, nums: List[int], k: int) -> List[int]: for num in nums: hash_map[num] = hash_map.get(num, 0) + 1 - # 인덱스 = 등장 횟수, 값 = 그 횟수만큼 등장한 숫자 리스트 + # 예시 nums = [1,6,6,3,2,6,8], bucket = [[1,3,2,8],[],[6]] bucket = [[] for _ in range(len(nums) + 1)] for num, count in hash_map.items(): bucket[count].append(num) From 0fd9c87231ca03cd43e47930c8917d7468a5d30c Mon Sep 17 00:00:00 2001 From: Seoya0512 Date: Sat, 15 Nov 2025 15:35:12 +0900 Subject: [PATCH 6/6] feat: week1 - longest consecutive sequence --- longest-consecutive-sequence/Seoya0512.py | 93 +++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 longest-consecutive-sequence/Seoya0512.py diff --git a/longest-consecutive-sequence/Seoya0512.py b/longest-consecutive-sequence/Seoya0512.py new file mode 100644 index 0000000000..8846d533ef --- /dev/null +++ b/longest-consecutive-sequence/Seoya0512.py @@ -0,0 +1,93 @@ +''' +1차시도 : 시간 복잡도 O(n)으로 해결 실패..;; +Approach +- nums 리스트가 비어있는 경우 0을 반환합니다. +- nums 리스트의 중복을 제거하고 정렬합니다. +- 정렬된 리스트를 순회하며 이전 숫자와 현재 숫자가 연속되는지 확인합니다. +- 연속된다면 count를 증가시키고, 연속되지 않는다면 max_count와 비교하여 갱신 후 count를 1로 초기화합니다. +- 최종적으로 max_count를 반환합니다. + +Time Complexity: O(n log n) +- 중복 제거 및 정렬에 O(n log n) 발생 + +Space Complexity: O(n) +- 중복 제거된 리스트 저장 공간으로 인해 O(n) 발생 +''' +class Solution: + def longestConsecutive(self, nums: List[int]) -> int: + # 리스트에 값이 없는 경우는 0 반환 + if len(nums) == 0: + return 0 + + # 정렬 + new_nums = list(set(nums)) + new_nums.sort() + # 변수 생성 : 배열의 길이가 1이상인 경우 연속되는 숫자는 무조건 1개 포함된다고 가정 + count = 1 + max_count = 1 + + for idx, val in enumerate(new_nums): + # 첫 번째 인덱트(idx == 0)는 비교할 이전 값이 없으므로 그냥 건너뛰기 + if idx == 0: + continue + if new_nums[idx-1] +1 == val: + count+=1 + # 마지막 값인 경우 + if idx == len(new_nums)-1: + if max_count <= count: + max_count = count + else: + # 이전갑과 연속되지 않는 경우 + if max_count <= count: + max_count = count + count = 1 + else: + count = 1 + + return max_count + +''' +2차시도 : Set 자료구조 활용 +Approach +- Set 자료구조로 중복 값을 제거하고, Set을 활용한 존재 여부 확인 시간은 O(1)이기 때문에 이를 활용했습니다. +- nums 리스트가 비어이는 경우 0을 반환합니다. +- Set으로 중복된 값을 제거합니다. +- Set을 순회하며 각 값에 대해 val-1이 Set에 없는 경우 새로운 연속 수열의 시작점으로 간주합니다. +- 시작점 이후로 While문을 사용해서 val+1, val+2,... 가 Set에 존재하는지 확인하며 count를 증가시킵니다. +- 최종적으로 max_count를 반환합니다. + +Time Complexity: O(n) +- Array를 Set으로 변환: O(n) +- 각 원소에 대해: + - 시작점이 아닌 경우: if (val - 1) not in num_set → O(1) 후 바로 넘어감 + - 시작점인 경우: while로 연속 구간을 끝까지 탐색: 각 숫자는 연속되는 숫자 내에서 최대 한 번씩만 방문되므로, + 전체 while 반복 횟수의 합은 O(n)을 넘지 않음. + +Space Complexity: O(n) +- Set 자료구조에 중복 제거된 값들을 저장하는데 O(n) 발생 +''' +class Solution: + def longestConsecutive(self, nums: List[int]) -> int: + # 값이 없는 경우 0 반환 + if len(nums) == 0: + return 0 + + # set으로 중복된 값 제거 + num_set = set(nums) + max_count = 1 + + for val in num_set: + # val-1 이 없다면, val은 새로운 연속 수열의 시작점 + if (val - 1) not in num_set: + current = val + count = 1 + + # 시작점 이후 연속되는 숫자가 set안에 있는지 검증 + while (current + 1) in num_set: + current += 1 + count += 1 + # while문 탈출 (=연속되는 숫자가 없는 경우) 최대 연속된 숫자 길이와 비교함 + if count > max_count: + max_count = count + + return max_count