From 6af0efb2c11e966f2fd1cb87ed0f26260f549f94 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Sun, 20 Jul 2025 23:45:17 +0900 Subject: [PATCH 1/7] contains duplicate & two sum --- contains-duplicate/hu6r1s.py | 12 ++++++++++++ two-sum/hu6r1s.py | 17 +++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 contains-duplicate/hu6r1s.py create mode 100644 two-sum/hu6r1s.py diff --git a/contains-duplicate/hu6r1s.py b/contains-duplicate/hu6r1s.py new file mode 100644 index 000000000..ddb66a0af --- /dev/null +++ b/contains-duplicate/hu6r1s.py @@ -0,0 +1,12 @@ +from collections import Counter + +class Solution: + # 시간복잡도: O(n) - Counter(nums)는 n번 순회하며 각 원소의 개수를 세고, cnt.items()는 최대 n개의 (key, value) 쌍을 포함하므로 최대 n번 순회 + # 공간복잡도: O(n) - Counter는 입력 배열에 있는 각 고유 원소를 키로 저장하므로 최악의 경우 n개의 키를 저장함 + def containsDuplicate(self, nums: List[int]) -> bool: + cnt = Counter(nums) + for _, v in cnt.items(): + if v >= 2: + return True + else: + return False \ No newline at end of file diff --git a/two-sum/hu6r1s.py b/two-sum/hu6r1s.py new file mode 100644 index 000000000..d1ff46d1a --- /dev/null +++ b/two-sum/hu6r1s.py @@ -0,0 +1,17 @@ +""" + - Time Complexity + - 바깥 for 루프는 n - 1번, 안쪽 루프는 최대 n - i - 1번 실행 + - 전체적으로 O(n^2)의 시간 복잡도를 가짐짐 + + - Space Complexity + - 별도의 자료구조를 사용하지 않음 + - 변수 i, j 그리고 리턴 시 사용하는 [i, j]만 존재 + - 따라서 O(1)의 공간 복잡도를 가짐짐 +""" + +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + for i in range(len(nums)-1): + for j in range(i+1, len(nums)): + if nums[i] + nums[j] == target: + return [i, j] \ No newline at end of file From b66f205a0451a2c5b5bbd131cec727a77173efbb Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Mon, 21 Jul 2025 00:14:43 +0900 Subject: [PATCH 2/7] fix: Add missing newline characters for proper formatting --- contains-duplicate/hu6r1s.py | 3 ++- two-sum/hu6r1s.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contains-duplicate/hu6r1s.py b/contains-duplicate/hu6r1s.py index ddb66a0af..1d8ead9ca 100644 --- a/contains-duplicate/hu6r1s.py +++ b/contains-duplicate/hu6r1s.py @@ -9,4 +9,5 @@ def containsDuplicate(self, nums: List[int]) -> bool: if v >= 2: return True else: - return False \ No newline at end of file + return False + \ No newline at end of file diff --git a/two-sum/hu6r1s.py b/two-sum/hu6r1s.py index d1ff46d1a..7e20e6e75 100644 --- a/two-sum/hu6r1s.py +++ b/two-sum/hu6r1s.py @@ -14,4 +14,5 @@ def twoSum(self, nums: List[int], target: int) -> List[int]: for i in range(len(nums)-1): for j in range(i+1, len(nums)): if nums[i] + nums[j] == target: - return [i, j] \ No newline at end of file + return [i, j] + \ No newline at end of file From 521c32aff12b558a09fbdf9cd0221ded0499ee08 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Mon, 21 Jul 2025 00:18:21 +0900 Subject: [PATCH 3/7] fix: Add missing newline characters for proper formatting --- contains-duplicate/hu6r1s.py | 1 - two-sum/hu6r1s.py | 1 - 2 files changed, 2 deletions(-) diff --git a/contains-duplicate/hu6r1s.py b/contains-duplicate/hu6r1s.py index 1d8ead9ca..ae2f2bd29 100644 --- a/contains-duplicate/hu6r1s.py +++ b/contains-duplicate/hu6r1s.py @@ -10,4 +10,3 @@ def containsDuplicate(self, nums: List[int]) -> bool: return True else: return False - \ No newline at end of file diff --git a/two-sum/hu6r1s.py b/two-sum/hu6r1s.py index 7e20e6e75..11a202825 100644 --- a/two-sum/hu6r1s.py +++ b/two-sum/hu6r1s.py @@ -15,4 +15,3 @@ def twoSum(self, nums: List[int], target: int) -> List[int]: for j in range(i+1, len(nums)): if nums[i] + nums[j] == target: return [i, j] - \ No newline at end of file From 2771cad0590ee2b32d31ebcedaa272b74cd3d776 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Mon, 21 Jul 2025 13:59:27 +0900 Subject: [PATCH 4/7] feat: Solve top-k-frequent-elements problem --- top-k-frequent-elements/hu6r1s.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 top-k-frequent-elements/hu6r1s.py diff --git a/top-k-frequent-elements/hu6r1s.py b/top-k-frequent-elements/hu6r1s.py new file mode 100644 index 000000000..82131cc98 --- /dev/null +++ b/top-k-frequent-elements/hu6r1s.py @@ -0,0 +1,18 @@ +from collections import Counter + +class Solution: + """ + - TC + - Counter(nums): O(n) + - sorted(): O(n log n) + - 슬라이싱 및 리스트 변환: O(k) + - 전체: O(n log n) + - SP + - Counter 및 정렬된 딕셔너리 저장: O(n) + - 반환 리스트: O(k) + - 전체: O(n) + """ + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + count_nums = Counter(nums) + count_nums = dict(sorted(count_nums.items(), reverse=True, key=lambda x: x[1])).keys() + return list(count_nums)[:k] From 63956b589c37fa8170d371e209aff3f1afc74e62 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Tue, 22 Jul 2025 11:37:26 +0900 Subject: [PATCH 5/7] feat: Solve longest-consecutive-sequence problem --- longest-consecutive-sequence/hu6r1s.py | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 longest-consecutive-sequence/hu6r1s.py diff --git a/longest-consecutive-sequence/hu6r1s.py b/longest-consecutive-sequence/hu6r1s.py new file mode 100644 index 000000000..6193f58d7 --- /dev/null +++ b/longest-consecutive-sequence/hu6r1s.py @@ -0,0 +1,31 @@ +class Solution: + """ + nums를 내림차순 sort하고, 차례대로 두 개의 차가 다음 차가 같다면 + 1 + 처음 차는 diff 변수에 저장하고, 진행되면서 diff를 업데이트 + 200, 100, 4, 3, 2, 1 + + 연속된 수열이라고 하여 1 이외의 다른 수가 올 수 있을 것이라고 판단하였지만 차이가 1로 나온다는 것을 확인 + + - TC + - set(nums) -> O(n) + - for -> O(n) + - while -> O(n) + - 전체 -> O(n) + - SC + - num_set -> O(n) + - 다른 변수들 -> O(1) + - 전체 -> O(n) + """ + def longestConsecutive(self, nums: List[int]) -> int: + num_set = set(nums) + longest = 0 + + for num in num_set: + if num - 1 not in num_set: + k = 1 + + while num + k in num_set: + k += 1 + + longest = max(longest, k) + return longest From 14418e2ae7a3dc4c3e074112340518c868e0db78 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Wed, 23 Jul 2025 21:38:35 +0900 Subject: [PATCH 6/7] feat: Solve house-robber problem --- house-robber/hu6r1s.py | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 house-robber/hu6r1s.py diff --git a/house-robber/hu6r1s.py b/house-robber/hu6r1s.py new file mode 100644 index 000000000..4bfe9e5cc --- /dev/null +++ b/house-robber/hu6r1s.py @@ -0,0 +1,45 @@ +class Solution: + """ + - 이전 풀이 + [1,2,3,1] + 인덱스 0에서 훔쳤을 때, 인덱스 1은 훔치면 안되므로 nums[0] + F(nums[2:]) + 인덱스 0에서 안훔쳤을 때, 인덱스 1에서 훔쳐야 하므로 F(nums[1:]) + + F[nums] = max(nums[0] + F[nums[2:]], F(nums[1:])) + F[i] = max(nums[i] + F(i+2), F(i+1)) + + + - dp + nums = [1, 2, 3, 1] + 집이 하나일 때는 한 곳만 볼 수 있으니 그 집의 돈을 훔침: dp[0] = nums[0] = 1 + 집이 두 개일 때, 인덱스 0인 곳을 갔다면 dp[0]이 가장 크고, + 가지 않았다면 인덱스 1을 가게 됨. dp[1] = max(dp[0], nums[1]) = max(1, 2) = 2 + 그래서 인덱스 0을 갔을 때와 가지 않았을 때를 고려하여 큰 돈을 가져옴 + 집이 세 개일 때, 인덱스 0을 갔다면 인덱스 2를 가야하고, 인덱스 0을 가지 않았다면 인덱스 1을 감 + 이를 고려하면, 인덱스 0을 갔을 때의 가장 큰 값이 dp[0]이고, 인덱스 2를 가야하니 nums[2]를 더한 값과 + 인덱스 0에 가지 않고 인덱스 1로 갔다면 dp[1]이 가장 크다. + 그래서 dp[2] = max(dp[0] + nums[2], dp[1]) + 집이 네 개일 때, 인덱스 3을 간다면 인덱스 1을 가게 되므로 인덱스 1까지의 dp 값과 인덱스 3의 값을 더한 값과 + 인덱스 3을 가지 않는다면 인덱스 0과 인덱스 2를 가게 된다. + 그렇다면 인덱스 2까지의 값을 비교하여 더 큰 돈을 가져간다. + 그래서 dp[3] = max(dp[1] + nums[3], dp[2])가 된다. + + - TC + - for loop -> O(n) + - SC + - dp 테이블 크기 -> O(n) + """ + def rob(self, nums: List[int]) -> int: + if not nums: + return 0 + if len(nums) == 1: + return nums[0] + + dp = [0] * len(nums) + dp[0] = nums[0] + dp[1] = max(dp[0], nums[1]) + + for i in range(2, len(nums)): + dp[i] = max(dp[i-2] + nums[i], dp[i-1]) + + return dp[-1] From 30ea21d2c43639aeb4d05eb6e12321ce55db243b Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Sat, 26 Jul 2025 17:44:44 +0900 Subject: [PATCH 7/7] fix: time complexity O(n^2) -> O(n) --- two-sum/hu6r1s.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/two-sum/hu6r1s.py b/two-sum/hu6r1s.py index 11a202825..09b97e2be 100644 --- a/two-sum/hu6r1s.py +++ b/two-sum/hu6r1s.py @@ -8,10 +8,20 @@ - 변수 i, j 그리고 리턴 시 사용하는 [i, j]만 존재 - 따라서 O(1)의 공간 복잡도를 가짐짐 """ +""" + class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + for i in range(len(nums)-1): + for j in range(i+1, len(nums)): + if nums[i] + nums[j] == target: + return [i, j] +""" class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: - for i in range(len(nums)-1): - for j in range(i+1, len(nums)): - if nums[i] + nums[j] == target: - return [i, j] + d = {num: idx for idx, num in enumerate(nums)} + + for i, v in enumerate(nums): + idx = target - v + if idx in d and d[idx] != i: + return [i, d[idx]]