From bbf0f2a6d31a9b149eb11ca08eef27e790d7d0d2 Mon Sep 17 00:00:00 2001 From: KyungJin Jung Date: Mon, 29 Jun 2026 20:22:28 +0900 Subject: [PATCH 1/6] 242. Valid Anagram --- valid-anagram/okyungjin.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 valid-anagram/okyungjin.py diff --git a/valid-anagram/okyungjin.py b/valid-anagram/okyungjin.py new file mode 100644 index 0000000000..7b418eee47 --- /dev/null +++ b/valid-anagram/okyungjin.py @@ -0,0 +1,32 @@ +# https://leetcode.com/problems/house-robber/description/ + +# [요구사항] +# 문자열 두 개가 주어졌을 때 애너그램이 맞는지 아닌지를 반환하는 문제 +# 애너그램이란? 하나의 단어나 구에 들어 있는 글자들을 모두, 각각 정확히 한 번씩만 사용해서 순서를 바꾸어 만든 다른 단어나 구를 의미한다. +# 두 문자열이 애너그램이면 True, 아니면 False 반환 + +# [접근법] +# 1. 길이가 다르면 애너그램이 아니므로 바로 False를 반환한다. +# 2. s의 문자 개수를 센 뒤, t를 순회하며 하나씩 차감한다. +# 3. 없는 문자이거나 개수가 부족한 문자를 만나면 False를 반환한다. +# 4. 모든 문자를 정상적으로 처리하면 True를 반환한다. + +# Time: O(N) +# Space: O(N) + +from collections import Counter + +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + if len(s) != len(t): + return False + + counter = Counter(s) + + for char in t: + if counter[char] >= 1: + counter[char] -= 1 + else: + return False + + return True From 3e04e11fdb08b9b890f2f28da8c4616f836cf85f Mon Sep 17 00:00:00 2001 From: KyungJin Jung Date: Wed, 1 Jul 2026 23:19:50 +0900 Subject: [PATCH 2/6] 70. Climbing Stairs --- climbing-stairs/okyungjin.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 climbing-stairs/okyungjin.py diff --git a/climbing-stairs/okyungjin.py b/climbing-stairs/okyungjin.py new file mode 100644 index 0000000000..48104dd462 --- /dev/null +++ b/climbing-stairs/okyungjin.py @@ -0,0 +1,24 @@ +# 시간 복잡도: O(N) +# 공간 복잡도: O(1) + +# [요구사항] +# 1. 계단의 개수 n이 주어진다. +# 2. 계단은 1칸 또는 2칸 올라갈 수 있다. +# 3. 마지막 칸에 도달할 수 있는 경우의 수를 반환한다. + +# [접근법] +# 1. 계단에 올라올 수 있는 경우의 수는 전전칸까지의 경우의 수 (prev2) + 전칸까지의 경우의 수 (prev1) 를 더한 값이다. +class Solution: + def climbStairs(self, n: int) -> int: + if n <= 2: + return n + + prev2 = 1 # 전전칸 까지의 경우의 수 + prev1 = 2 # 전칸 까지의 경우의 수 + + for _ in range(2, n): + curr = prev2 + prev1 # 현재 계단 + prev2 = prev1 + prev1 = curr + + return prev1 From 91141cae97416244d818ba9be83ed95b6792f5e3 Mon Sep 17 00:00:00 2001 From: KyungJin Jung Date: Sat, 4 Jul 2026 20:31:25 +0900 Subject: [PATCH 3/6] 238. Product of Array Except Self --- product-of-array-except-self/okyungjin.py | 38 +++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 product-of-array-except-self/okyungjin.py diff --git a/product-of-array-except-self/okyungjin.py b/product-of-array-except-self/okyungjin.py new file mode 100644 index 0000000000..7981c8f0e5 --- /dev/null +++ b/product-of-array-except-self/okyungjin.py @@ -0,0 +1,38 @@ +# [요구사항] +# 정수배열 nums가 주어진다. +# answer[i]는 nums[i]를 제외한 나머지 숫자의 곱이다. +# answer 배열을 반환한다. +# 단, 나눗셈 없이 O(N)으로 알고리즘을 작성해야한다. + +# [접근법] +# 처음에는 조합(combinations)으로 모든 경우를 구하려 했지만 +# 시간 복잡도가 O(N²) 이상이 되어 시간 초과가 발생했습니다. + +# (고민해보다가 AI의 도움을 받아 힌트를 얻었습니다.) +# 각 위치에서 왼쪽 누적 곱(prefix)과 오른쪽 누적 곱(suffix)을 각각 구해 곱하는 방식으로 풀었습니다. + +# 예시) +# nums = [1, 2, 3, 4] +# prefix = [1, 1, 2, 6] -> 각 위치의 왼쪽 원소들의 곱 +# suffix를 뒤에서부터 누적하면서 answer에 곱해줍니다. +# 최종 answer 배열 [24, 12, 8, 6] + +# 시간 복잡도 : O(N) +# 공간 복잡도 : O(1) (정답 배열 제외) +class Solution: + def productExceptSelf(self, nums: List[int]) -> List[int]: + size = len(nums) + + answer = [] + + prefix = 1 + for i in range(size): + answer.append(prefix) + prefix *= nums[i] + + suffix = 1 + for j in reversed(range(size)): + answer[j] *= suffix + suffix *= nums[j] + + return answer From dfd817b4f5dd7e235dbdf559be13c949eead56f6 Mon Sep 17 00:00:00 2001 From: KyungJin Jung Date: Sat, 4 Jul 2026 20:50:33 +0900 Subject: [PATCH 4/6] 238. Product of Array Except Self --- product-of-array-except-self/okyungjin.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/product-of-array-except-self/okyungjin.py b/product-of-array-except-self/okyungjin.py index 7981c8f0e5..d81fc5e9f7 100644 --- a/product-of-array-except-self/okyungjin.py +++ b/product-of-array-except-self/okyungjin.py @@ -19,6 +19,8 @@ # 시간 복잡도 : O(N) # 공간 복잡도 : O(1) (정답 배열 제외) +from typing import List + class Solution: def productExceptSelf(self, nums: List[int]) -> List[int]: size = len(nums) @@ -36,3 +38,6 @@ def productExceptSelf(self, nums: List[int]) -> List[int]: suffix *= nums[j] return answer + +print(Solution().productExceptSelf([1,2,3,4])) +print(Solution().productExceptSelf([2,5,3,7])) From 5105a32b0c4ff6bd0212ee2f285f9f3abd41d770 Mon Sep 17 00:00:00 2001 From: KyungJin Jung Date: Sat, 4 Jul 2026 20:55:54 +0900 Subject: [PATCH 5/6] 242. Valid Anagram --- valid-anagram/okyungjin.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/valid-anagram/okyungjin.py b/valid-anagram/okyungjin.py index 7b418eee47..47b402d122 100644 --- a/valid-anagram/okyungjin.py +++ b/valid-anagram/okyungjin.py @@ -1,4 +1,4 @@ -# https://leetcode.com/problems/house-robber/description/ +# https://leetcode.com/problems/valid-anagram/description/ # [요구사항] # 문자열 두 개가 주어졌을 때 애너그램이 맞는지 아닌지를 반환하는 문제 @@ -16,7 +16,7 @@ from collections import Counter -class Solution: +class Solution01: def isAnagram(self, s: str, t: str) -> bool: if len(s) != len(t): return False @@ -30,3 +30,12 @@ def isAnagram(self, s: str, t: str) -> bool: return False return True + +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + if len(s) != len(t): + return False + + # 파이썬은 == 로 값을 비교한다. + # 참조로 비교하려면 is 사용 + return Counter(s) == Counter(t) From a3585d3710fb4b065c7f31786979c1364f44c5cf Mon Sep 17 00:00:00 2001 From: KyungJin Jung Date: Sat, 4 Jul 2026 22:23:59 +0900 Subject: [PATCH 6/6] 15. 3Sum --- 3sum/okyungjin.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 3sum/okyungjin.py diff --git a/3sum/okyungjin.py b/3sum/okyungjin.py new file mode 100644 index 0000000000..c94426e0b0 --- /dev/null +++ b/3sum/okyungjin.py @@ -0,0 +1,63 @@ +# [문제 링크] +# https://leetcode.com/problems/3sum/ + +# [요구사항] +# - nums 배열이 주어지고, nums[i] + nums[j] + nums[k] 를 더했을 때 0이 는 숫자 3개의 배열을 반환한다. +# - 결과 집합은 1개 이상임 +# - 정답에 중복이 있으면 안 된다! +# - `3 <= nums.length <= 3000` + +# [접근법] +# 1. 포인터를 3개 선언하고, 하나를 고정한 채로 2Sum으로 나머지 해를 찾는다. +# 2. 중복 제거를 위해 포인터를 좌우로 움직여줘야 한다. + +# 시간 복잡도: O(N^2) +# 공간 복잡도: O(N) + +class Solution: + def threeSum(self, nums: list[int]) -> list[list[int]]: + size = len(nums) + answer = [] + + # 포인터를 사용하기 위해 배열을 정렬한다 + nums.sort() + + # 포인터 3개 중 하나를 고정한다. + for i in range(size - 2): + # 중복 제거 + if i > 0 and nums[i] == nums[i - 1]: + continue + + # 나머지 두 개의 포인터를 left, right라 한다. 양 끝을 할당 + left = i + 1 + right = size - 1 + + while left < right: + total = nums[i] + nums[left] + nums[right] + + # 합이 0보다 작으면 더 큰 숫자를 더해줘야 하므로 left를 우측으로 이동 + if total < 0: + left += 1 + + # 합이 0보다 크면 더 작은 숫자를 더해줘야 하므로 right을 좌측으로 이동 + elif total > 0: + right -= 1 + + # 숫자 3개가 합쳐서 0인 경우 (해를 찾음) + else: + # 정답에 추가하고 + answer.append([nums[i], nums[left], nums[right]]) + + # 포인터를 안쪽으로 한칸 이동한다. + left += 1 + right -= 1 + + # left 중복 제거를 위해 이동 + while left < right and nums[left] == nums[left - 1]: + left += 1 + + # right 중복 제거를 위해 이동 + while left < right and nums[right] == nums[right + 1]: + right -= 1 + + return answer