From 5768268d12f8f5aa6ed9d13cc80aa15ad427f90c Mon Sep 17 00:00:00 2001 From: JinuCheon Date: Sat, 27 Jun 2026 21:20:15 +0900 Subject: [PATCH 1/8] 217. Contains Duplicate --- contains-duplicate/JinuCheon.java | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 contains-duplicate/JinuCheon.java diff --git a/contains-duplicate/JinuCheon.java b/contains-duplicate/JinuCheon.java new file mode 100644 index 0000000000..a05c59a0b7 --- /dev/null +++ b/contains-duplicate/JinuCheon.java @@ -0,0 +1,28 @@ +import java.util.HashSet; +import java.util.Set; + +class Solution { + /** + * 79/79 cases passed (19 ms) + * Your runtime beats 32.04 % of java submissions + * Your memory usage beats 6.16 % of java submissions (108.1 MB) + * + * When I changed HashSet to LinkedHashSet, the runtime and memory usage increased a little bit. + * + * Improvement: + * if (!set.add(num)) return true; // when num is already in the set, return true. + * It looks like more simple. + */ + public boolean containsDuplicate(int[] nums) { + Set exist = new HashSet<>(); + + for (int num : nums) { + if (exist.contains(num)) { + return true; + } else { + exist.add(num); + } + } + return false; + } +} From 45f13c415b19638c5d1921d6585beaf88281ab56 Mon Sep 17 00:00:00 2001 From: JinuCheon Date: Sat, 27 Jun 2026 22:52:52 +0900 Subject: [PATCH 2/8] Two Sum --- two-sum/JinuCheon.java | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 two-sum/JinuCheon.java diff --git a/two-sum/JinuCheon.java b/two-sum/JinuCheon.java new file mode 100644 index 0000000000..a67acc1341 --- /dev/null +++ b/two-sum/JinuCheon.java @@ -0,0 +1,36 @@ +// Follow-up: Can you come up with an algorithm that is less than O(n2) time complexity? +// O(n2) +// class Solution1 { +// public int[] twoSum(int[] nums, int target) { +// int size = nums.length; +// for (int i=0; i map = new HashMap<>(); + + for (int i = 0; i < nums.length; i++) { + int pair = target - nums[i]; + + if (map.containsKey(pair)) { + return new int[]{i, map.get(pair)}; + } + + map.put(nums[i], i); + } + throw new IllegalArgumentException(); + } +} From b174a0f6422f74d60104b6074109e3b8e3b07e9c Mon Sep 17 00:00:00 2001 From: JinuCheon Date: Mon, 29 Jun 2026 22:50:46 +0900 Subject: [PATCH 3/8] valid anagram --- valid-anagram/JinuCheon.py | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 valid-anagram/JinuCheon.py diff --git a/valid-anagram/JinuCheon.py b/valid-anagram/JinuCheon.py new file mode 100644 index 0000000000..1966dd6b16 --- /dev/null +++ b/valid-anagram/JinuCheon.py @@ -0,0 +1,39 @@ +# my own solution +# O(n) +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + count1 = {} + for ch in s: + count1[ch] = count1.get(ch, 0) + 1 + + count2 = {} + for ch in t: + count2[ch] = count2.get(ch, 0) + 1 + + return count1 == count2 + +# gpt suggestion +### half space +#### O(n) +class Solution2: + def isAnagram(self, s: str, t: str) -> bool: + count = {} + for ch in s: + count[ch] = count.get(ch, 0) + 1 + for ch in t: + count[ch] = count.get(ch, 0) - 1 + return all(v == 0 for v in count.values()) + +### simple solution (What??) +#### O(n) +#### Counter works like my own solution internally. But I'm ganna forgot this, becuase I'm learning now. +from collections import Counter +class Solution3: + def isAnagram(self, s: str, t: str) -> bool: + return Counter(s) == Counter(t) + +### using sort +#### O(n log n) +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + return sorted(s) == sorted(t) \ No newline at end of file From b60683106d92334c4591861b4963710846568a3f Mon Sep 17 00:00:00 2001 From: JinuCheon Date: Wed, 1 Jul 2026 23:26:22 +0900 Subject: [PATCH 4/8] climbing stairs --- climbing-stairs/JinuCheon.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 climbing-stairs/JinuCheon.py diff --git a/climbing-stairs/JinuCheon.py b/climbing-stairs/JinuCheon.py new file mode 100644 index 0000000000..e8e6215e45 --- /dev/null +++ b/climbing-stairs/JinuCheon.py @@ -0,0 +1,32 @@ +# 재귀를 만드는 것이 잘 생각나지 않아서, 이렇게 저렇게 시도해보다 결국 LLM 도움. +# 그렇지만 제출 결과 Time Out. +# 2^N 복잡도임. max 45 의 경우 35,184,372,088,832. +class Solution: + def climbStairs(self, n: int) -> int: + # 1 -> 한칸만 가능 + # 2 -> (1,1) or (2) + if n <= 2: + return n; + + # 1칸 진행한 케이스 + 2칸 진행한 케이스 + return self.climbStairs(n-1) + self.climbStairs(n-2); + +# memonization 적용. 실무를 하고나서 이걸 보니, 캐싱이라고 부르고 싶다. +# 1~N 숫자 하나당 한번의 계산을 하게 되니, 시간복잡도는 O(1) 이다. +# 이게 왜 easy 난이도지? 잊어먹었다가 주말에 자력으로 풀어보자. +class Solution: + def climbStairs(self, n: int) -> int: + self.memo = {} + return self.dfs(n) + + def dfs(self, n: int) -> int: + if n <= 2: + return n + + # 이미 해당 수를 계산한 적이 있다면 early return. + if n in self.memo: + return self.memo[n] + + # 새로운 결과가 있으면 무조건 저장. + self.memo[n] = self.dfs(n - 1) + self.dfs(n - 2) + return self.memo[n] \ No newline at end of file From 794ad7d8f68fcb356ece0f9c05aafeb5a3c6f39d Mon Sep 17 00:00:00 2001 From: JinuCheon Date: Sat, 4 Jul 2026 15:12:43 +0900 Subject: [PATCH 5/8] add line break --- climbing-stairs/JinuCheon.py | 3 ++- valid-anagram/JinuCheon.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/climbing-stairs/JinuCheon.py b/climbing-stairs/JinuCheon.py index e8e6215e45..4f61a73238 100644 --- a/climbing-stairs/JinuCheon.py +++ b/climbing-stairs/JinuCheon.py @@ -29,4 +29,5 @@ def dfs(self, n: int) -> int: # 새로운 결과가 있으면 무조건 저장. self.memo[n] = self.dfs(n - 1) + self.dfs(n - 2) - return self.memo[n] \ No newline at end of file + return self.memo[n] + \ No newline at end of file diff --git a/valid-anagram/JinuCheon.py b/valid-anagram/JinuCheon.py index 1966dd6b16..969d5c5b67 100644 --- a/valid-anagram/JinuCheon.py +++ b/valid-anagram/JinuCheon.py @@ -36,4 +36,4 @@ def isAnagram(self, s: str, t: str) -> bool: #### O(n log n) class Solution: def isAnagram(self, s: str, t: str) -> bool: - return sorted(s) == sorted(t) \ No newline at end of file + return sorted(s) == sorted(t) From 37dc7f91a538f37f2f48af4c63e7380f3545efeb Mon Sep 17 00:00:00 2001 From: JinuCheon Date: Sat, 4 Jul 2026 15:26:50 +0900 Subject: [PATCH 6/8] =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81:=20?= =?UTF-8?q?=EC=A0=90=ED=99=94=EC=8B=9D=20=EC=A0=81=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=9E=AC=EA=B7=80=ED=98=B8=EC=B6=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- climbing-stairs/JinuCheon.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/climbing-stairs/JinuCheon.py b/climbing-stairs/JinuCheon.py index 4f61a73238..1e228edeb9 100644 --- a/climbing-stairs/JinuCheon.py +++ b/climbing-stairs/JinuCheon.py @@ -30,4 +30,24 @@ def dfs(self, n: int) -> int: # 새로운 결과가 있으면 무조건 저장. self.memo[n] = self.dfs(n - 1) + self.dfs(n - 2) return self.memo[n] - \ No newline at end of file + + +# yuseok89 님 피드백 반영. +# 점화식(recursive relation): 수열의 항을 그 이전 항들을 이용해서 정의하는 식. +# 함수 호출 오버헤드 제거 & 안정성 +class Solution3: + def climbStairs(self, n: int) -> int: + if n < 2: + return n + + dp = [0] * (n+1) + + # set init values + dp[1] = 1 + dp[2] = 2 + + # i 번째 계단 오르는 경우의 수: 1칸 + 2칸 경우의 수의 합 + for i in range(3, n+1): + dp[i] = dp[i - 1] + dp[i - 2] + + return dp[n]; From 33a3efefea0f27af0677abc852f8cde7d85f1d17 Mon Sep 17 00:00:00 2001 From: JinuCheon Date: Sat, 4 Jul 2026 17:09:25 +0900 Subject: [PATCH 7/8] Product of Array Except Self --- product-of-array-except-self/JinuCheon.py | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 product-of-array-except-self/JinuCheon.py diff --git a/product-of-array-except-self/JinuCheon.py b/product-of-array-except-self/JinuCheon.py new file mode 100644 index 0000000000..89e243e00f --- /dev/null +++ b/product-of-array-except-self/JinuCheon.py @@ -0,0 +1,33 @@ +# 처음에 직관적으로 떠오른 O(n2) 풀이. +class Solution: + def productExceptSelf(self, nums: List[int]) -> List[int]: + n = len(nums) + result = [1] * n + for i in range(n): + for j in range(n): + if i == j: + continue + result[j] *= nums[i] + + return result + +# 고민하다가 LLM 에게 힌트 달라고 질문. +# 좌 / 우 누적곱으로 처리하는 방식. +class Solution: + def productExceptSelf(self, nums: List[int]) -> List[int]: + n = len(num) + result = [1] * n + + # 왼쪽 누적곱을 result에 미리 채워둠 + cumulativeLeftSum = 1 + for i in range(n): + result[i] = cumulativeLeftSum + cumulativeLeftSum *= nums[i] + + # 오른쪽 누적곱을 곱해나가면서 완성 + cumulativeRightSum = 1 + for i in range(n - 1, -1, -1): + result[i] *= cumulativeRightSum + cumulativeRightSum *= nums[i] + + return result From 69451cb03753fa569ffc789805aff2dd54744ec4 Mon Sep 17 00:00:00 2001 From: JinuCheon Date: Sat, 4 Jul 2026 18:01:38 +0900 Subject: [PATCH 8/8] threeSum --- 3sum/JinuCheon.py | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 3sum/JinuCheon.py diff --git a/3sum/JinuCheon.py b/3sum/JinuCheon.py new file mode 100644 index 0000000000..fcb586b578 --- /dev/null +++ b/3sum/JinuCheon.py @@ -0,0 +1,87 @@ +# brute force 로 풀어본 답안. O(n3) 다. 역시 timeout. +# dic, set 자료형 익히기 겸 해봤다. 파이썬 편하다 최고. +class Solution: + def threeSum(self, nums: list[int]) -> list[list[int]]: + n = len(nums) + result = set() + + for i in range(n): + for j in range(n): + for k in range(n): + if (i == j or j == k or i == k): + continue + if (nums[i] + nums[j] + nums[k] == 0): + result.add(tuple(sorted([nums[i], nums[j], nums[k]]))) + + return list(result) + +# LLM 에게 힌트 얻어서 진행. +# i != j, i != k, j != k 조건 때문에 정렬을 하면 안된다고 착각하고 있었다. 사실 고정된 순서는 중요하지 않음. +# 정렬을 진행하고, two pointer 로 진행. +# 통과! +class Solution2: + def threeSum(self, nums: list[int]) -> list[list[int]]: + # 정렬 + nums.sort() + n = len(nums) + result = set() + + for i in range(n): + # i 자리 중복 skip (이전 원소와 같으면 건너뜀) + if i > 0 and nums[i] == nums[i - 1]: + continue + + # i + left + right === 0 이 되어야 함. + left = i + 1 + right = n - 1 + + while left < right: + if nums[left] + nums[right] == -nums[i]: + result.add(tuple([nums[i], nums[left], nums[right]])) + left += 1 + right -= 1 + + elif nums[left] + nums[right] < -nums[i]: + left += 1 + else: + right -= 1 + + return list(result) + +# LLM의 피드백. +# 중복을 스킵하는 효율적인 방법이 있었음. +class Solution: + def threeSum(self, nums: list[int]) -> list[list[int]]: + nums.sort() + n = len(nums) + result = [] + + for i in range(n): + if i > 0 and nums[i] == nums[i - 1]: + continue + + if nums[i] > 0: + break + + left, right = i + 1, n - 1 + target = -nums[i] + + while left < right: + s = nums[left] + nums[right] + if s == target: + result.append([nums[i], nums[left], nums[right]]) + left += 1 + right -= 1 + + # left, right 자리도 중복 skip + while left < right and nums[left] == nums[left - 1]: + left += 1 + while left < right and nums[right] == nums[right + 1]: + right -= 1 + + elif s < target: + left += 1 + else: + right -= 1 + + return result