From 4a966b411172243957a5f461df84079922bdb079 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Sun, 27 Jul 2025 19:05:58 +0900 Subject: [PATCH 1/6] feat: Solve valid-anagram problem --- valid-anagram/hu6r1s.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 valid-anagram/hu6r1s.py diff --git a/valid-anagram/hu6r1s.py b/valid-anagram/hu6r1s.py new file mode 100644 index 000000000..6e66255c7 --- /dev/null +++ b/valid-anagram/hu6r1s.py @@ -0,0 +1,33 @@ +from collections import defaultdict + +class Solution: + """ + 1. Counter를 이용한 풀이 + - Counter로 풀이하였으나 s, t 길이가 서로 다를 때 해결되지 않음 + 2. defaultdict 활용 풀이 + - 똑같이 개수 세고 제외 + + TC + - s의 길이: n, t의 길이: n (조건상 같거나 비교 가능한 길이) + - 첫 번째 for 루프: O(n) → s의 모든 문자를 순회 + - 두 번째 for 루프: O(n) → t의 모든 문자를 순회 + - 총 시간 복잡도 = O(n) + + SC + - counter는 알파벳 개수를 세는 용도로만 사용됨 + - 공간 복잡도 = O(1) + """ + def isAnagram(self, s: str, t: str) -> bool: + counter = defaultdict(int) + + for i in s: + counter[i] += 1 + + for i in t: + if i not in counter: + return False + counter[i] -= 1 + + if counter[i] == 0: + del counter[i] + return False if counter else True From 7b8df80a0308cdf4aa86113a76f5c9e7e94d83f7 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Sun, 27 Jul 2025 19:26:06 +0900 Subject: [PATCH 2/6] feat: Solve climbing-stairs problem --- climbing-stairs/hu6r1s.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 climbing-stairs/hu6r1s.py diff --git a/climbing-stairs/hu6r1s.py b/climbing-stairs/hu6r1s.py new file mode 100644 index 000000000..38f99d578 --- /dev/null +++ b/climbing-stairs/hu6r1s.py @@ -0,0 +1,25 @@ +class Solution: + """ + 1일 때, 1 step -> 1개 + 2일 때, 1 + 1, 2 -> 2개 + 3일 때, 1 + 1 + 1, 1 + 2, 2 + 1 -> 3개 + 4일 때, 1 + 1 + 1 + 1, 1 + 1 + 2, 1 + 2 + 1, 2 + 1 + 1, 2 + 2 -> 5개 + 5일 때, 1 + 1 + 1 + 1 + 1, 1 + 1 + 1 + 2, 1 + 1 + 2 + 1, 1 + 2 + 1 + 1, 2 + 1 + 1 + 1, 1 + 2 + 2, 2 + 1 + 2, 2 + 2 + 1 -> 8개 + 순서대로 봤을 때, 이전 값과 그 이전 값의 합이 현재 개수이다. + 이를 점화식으로 봤을 때, dp[i] = d[i - 1] + dp[i - 2]가 된다. + + - Time Complexity: O(n) + - 1부터 n까지 한 번씩 반복하므로 선형 시간 + - Space Complexity: O(n) + - dp 배열에 n개의 값을 저장하므로 선형 공간 사용 + """ + def climbStairs(self, n: int) -> int: + if n == 1: + return n + + dp = [0] * n + dp[0] = 1 + dp[1] = 2 + for i in range(2, n): + dp[i] = dp[i - 1] + dp[i - 2] + return dp[-1] From be7853c6d0585f18e70b2a428996ebbff81879e9 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Tue, 29 Jul 2025 11:38:40 +0900 Subject: [PATCH 3/6] feat: Solve 3sum problem --- 3sum/hu6r1s.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 3sum/hu6r1s.py diff --git a/3sum/hu6r1s.py b/3sum/hu6r1s.py new file mode 100644 index 000000000..9650ad42c --- /dev/null +++ b/3sum/hu6r1s.py @@ -0,0 +1,37 @@ +class Solution: + """ + 1. 3 way for문으로 돌아가면서 0인 합을 찾는 방법 + - O(n^3)으로 시간초과 + 2. 투포인터 + - 정렬 후 투포인터를 이용하여 중복 제거와 최적화를 동시에 수행 + - O(n^2) + 공간 복잡도는 둘다 O(1) + """ + def threeSum(self, nums: List[int]) -> List[List[int]]: + result = [] + nums.sort() + + for i in range(len(nums)): + if i > 0 and nums[i] == nums[i - 1]: + continue + + left, right = i + 1, len(nums) - 1 + while left < right: + total = nums[i] + nums[left] + nums[right] + + if total == 0: + result.append([nums[i], nums[left], nums[right]]) + left += 1 + right -= 1 + + while left < right and nums[left] == nums[left - 1]: + left += 1 + while left < right and nums[right] == nums[right + 1]: + right -= 1 + + elif total < 0: + left += 1 + else: + right -= 1 + + return result From 588fe0e1b749370531b5e078e8b473e6698d2858 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Wed, 30 Jul 2025 18:35:55 +0900 Subject: [PATCH 4/6] feat: Solve product-of-array-except-self problem --- product-of-array-except-self/hu6r1s.py | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 product-of-array-except-self/hu6r1s.py diff --git a/product-of-array-except-self/hu6r1s.py b/product-of-array-except-self/hu6r1s.py new file mode 100644 index 000000000..56a01fe5f --- /dev/null +++ b/product-of-array-except-self/hu6r1s.py @@ -0,0 +1,34 @@ +import math + +class Solution: + """ + 1. 인덱스 슬라이싱을 활용한 풀이 + - 인덱스 슬라이싱을 활용하여 해당 인덱스를 제외한 나머지 원소들의 곲을 math.prod()를 이용하여 배열에 삽입 + - 시간초과 O(n^2) + 2. DP Bottom Up 방식으로 풀이 + - 인덱스 i에 대한 왼쪽 부분과 오른쪽 부분의 곱을 계산하는 방식 + - 시간 복잡도 O(n) + - 공간 복잡도 O(1) + """ + # 1번 풀이 + # def productExceptSelf(self, nums: List[int]) -> List[int]: + # answer = [1] * len(n) + + # for i in range(len(nums)): + # answer.append(math.prod(nums[:i] + nums[i+1:])) + + # return answer + + def productExceptSelf(self, nums: List[int]) -> List[int]: + dp = [1] * len(nums) + + left = 1 + for i in range(len(nums)): + dp[i] = left + left *= nums[i] + + right = 1 + for i in range(len(nums) - 1, -1, -1): + dp[i] *= right + right *= nums[i] + return dp From 9905e5b48d348b966afcc9ac79d8fe0ccf12c230 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Wed, 30 Jul 2025 22:39:20 +0900 Subject: [PATCH 5/6] feat: Solve validate-binary-search-tree problem --- validate-binary-search-tree/hu6r1s.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 validate-binary-search-tree/hu6r1s.py diff --git a/validate-binary-search-tree/hu6r1s.py b/validate-binary-search-tree/hu6r1s.py new file mode 100644 index 000000000..75c3769ef --- /dev/null +++ b/validate-binary-search-tree/hu6r1s.py @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + """ + TC: O(n) + SC: 최악의 경우 -> O(n), 평균 -> O(log n) + - 트리가 균일할 경우 평균의 복잡도가 나오고 + - 한쪽이 치우친 경우 최악의 경우로 나온다. + """ + def isValidBST(self, root: Optional[TreeNode]) -> bool: + def validate(node, left, right): + if not node: + return True + if not (left < node.val < right): + return False + return validate(node.left, left, node.val) and validate(node.right, node.val, right) + return validate(root, float("-inf"), float("inf")) From 2cde15abf760ee03b8f461d5b6f0a72b979211f5 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Wed, 30 Jul 2025 23:13:39 +0900 Subject: [PATCH 6/6] refactor: data structure list -> set to 3sum problem --- 3sum/hu6r1s.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/3sum/hu6r1s.py b/3sum/hu6r1s.py index 9650ad42c..2bd132c11 100644 --- a/3sum/hu6r1s.py +++ b/3sum/hu6r1s.py @@ -8,30 +8,21 @@ class Solution: 공간 복잡도는 둘다 O(1) """ def threeSum(self, nums: List[int]) -> List[List[int]]: - result = [] + result = set() nums.sort() - for i in range(len(nums)): - if i > 0 and nums[i] == nums[i - 1]: - continue - + for i in range(len(nums)): left, right = i + 1, len(nums) - 1 while left < right: total = nums[i] + nums[left] + nums[right] if total == 0: - result.append([nums[i], nums[left], nums[right]]) + result.add((nums[i], nums[left], nums[right])) left += 1 right -= 1 - - while left < right and nums[left] == nums[left - 1]: - left += 1 - while left < right and nums[right] == nums[right + 1]: - right -= 1 - elif total < 0: left += 1 else: right -= 1 - return result + return list(result)