From ec7bac7185e1edf83d4bedc4d70ef8c0accc9be1 Mon Sep 17 00:00:00 2001 From: namucy Date: Tue, 23 Jun 2026 15:14:52 +0900 Subject: [PATCH 01/12] house-robber solution --- house-robber/namuuCY.java | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 house-robber/namuuCY.java diff --git a/house-robber/namuuCY.java b/house-robber/namuuCY.java new file mode 100644 index 0000000000..b0e8403fb5 --- /dev/null +++ b/house-robber/namuuCY.java @@ -0,0 +1,76 @@ +class Solution { +/* + +문제 이해 +1. 1자로 주욱 나열되어있는 집 : 인접한다는 것은 index가 1차이 난다는 것 +2. 인접하는 두 집을 연속해서 털면 안된다. +3. 2의 제약조건을 가지고 털 수 있는 돈의 최대 합 + +문제 해결을 위한 의식의 흐름 +- 이거 예전에 백준에서 봤던 문제같음. +- 어떤 한 집을 방문할 때, 앞 집이 털렸을 경우와 털리지 않았을 경우를 모두 고려해야함. +- 맨 처음으로 DP를 생각하게 됨. + - 털렸을 경우와 털리지 않았을 경우의 값을 모두 저장해놔야 할 것으로 생각 + - 2차원 배열 DP를 아래와 같이 정의한다면 + - DP[0-안털었다 or 1-털었다][index] = index번째 집까지 왔을때 훔친 돈의 총합 + 1. 총합이므로 자료형은 int 만으로 충분? long 배열써야하는지? + - nums[i]가 최대 400이고, nums 길이가 100 이하 이므로 int로도 충분 + 2. DP 채워지는건 어떻게? 점화식 + - i번째 집을 방문할 때 + - i번째 집을 턴다고 가정 : i - 1 번째 집은 털지 않은 상태 + 현재 집의 돈 + - i번째 집을 털지 않는다고 가정 : i - 1 번째 집은 털어도 되고, 털지 않아도 됨 두 개중 최댓값 + 3. 이렇게 DP를 정의할 경우, DAG인가? + - i번째 집의 정보는 i-1번째 집의 정보로부터만 오기 때문에 DAG이다. + - 엣지케이스? : + - 맨 처음 index + DP[0][0] = 0 / 0이면 더하지 않고, + DP[0][0] = nums[0] / 1이면 더한다 + - 길이가 1이면? +- 쓰다보니 느낀건데 어차피 이전 집의 값만 필요하니까 굳이 DP를 사용안해도 될 것 같은데? + - 이렇게 하면 array 로 데이터 저장할 필요 X + + +시공간복잡도 +N : nums의 길이 +- DP 풀이 : + - 시간 복잡도 : O(N) + - 공간 복잡도 : O(N) // N * 2 개만큼 저장해야함. +- DP X 풀이 : + - 시간 복잡도 : O(N) + - 공간 복잡도 : O(1) // 이전 값 2개만 저장하면 됨. + +*/ + +/* DP 풀이 + public int rob(int[] nums) { + int[][] DP = new int[2][nums.length]; + DP[1][0] = nums[0]; + + for (int idx = 1 ; idx < nums.length; idx ++) { + DP[1][idx] = DP[0][idx - 1] + nums[idx]; + DP[0][idx] = Math.max(DP[0][idx - 1], DP[1][idx - 1]); + } + + return Math.max(DP[0][nums.length - 1], DP[1][nums.length - 1]); + } +*/ + + // DP X, 일반 순회 풀이 + public int rob(int[] nums) { + int robbed = 0; + int unrobbed = 0; + + int prevRobbed; + int prevUnrobbed; + + for (int money : nums) { + prevRobbed = robbed; // 0 1 2 4 + prevUnrobbed = unrobbed; // 0 0 1 2 + + robbed = prevUnrobbed + money; // 1 2 4 3 + unrobbed = Math.max(prevUnrobbed, prevRobbed); // 0 1 2 4 + } + + return Math.max(robbed, unrobbed); + } +} From 5fa58c343427a22d4b4296400f2c162f2e3c899c Mon Sep 17 00:00:00 2001 From: namucy Date: Fri, 26 Jun 2026 00:22:45 +0900 Subject: [PATCH 02/12] contains duplicate solution --- contains-duplicate/namuuCY.java | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 contains-duplicate/namuuCY.java diff --git a/contains-duplicate/namuuCY.java b/contains-duplicate/namuuCY.java new file mode 100644 index 0000000000..a2c5afc3b7 --- /dev/null +++ b/contains-duplicate/namuuCY.java @@ -0,0 +1,34 @@ +/** + + 문제 이해 + - 주어진 숫자열에 여러 숫자가 주어지고, + - 두 번 이상 동일한 숫자가 나온다면 true, 그렇지 않다면 false + + + 문제 해결을 위한 의식의 흐름 + - 맨처음에는 숫자 범위가 작다면 count를 위한 array를 생각 + - 숫자 범위가 int 범위 가까이 된다면, 시공간 복잡도 초과 + - 기록하고, query 가 빠르게 이뤄지는 자료구조 필요 + - count를 위해 숫자를 굳이 저장할 필요가 없고, 존재하는지만 확인하면 된다. + -> Set 자료구조 필요성 + + 시공간 복잡도 + - nums의 length를 N 이라 하면, + - 시간복잡도 : O(N) - N번 순회, 매 query별로 이론상 O(1) + - 공간복잡도 : O(N) + +*/ + + +class Solution { + public boolean containsDuplicate(int[] nums) { + Set numberContainer = new HashSet<>(); + + for (int number : nums) { + if (numberContainer.contains(number)) return true; + numberContainer.add(number); + } + + return false; + } +} From 53b976059971c5ccb398c8e2f2e9f75297352e91 Mon Sep 17 00:00:00 2001 From: namucy Date: Fri, 26 Jun 2026 10:58:21 +0900 Subject: [PATCH 03/12] =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contains-duplicate/namuuCY.java | 36 +++++++------- house-robber/namuuCY.java | 83 +++++++++++++++++---------------- 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/contains-duplicate/namuuCY.java b/contains-duplicate/namuuCY.java index a2c5afc3b7..5d00828f87 100644 --- a/contains-duplicate/namuuCY.java +++ b/contains-duplicate/namuuCY.java @@ -1,23 +1,23 @@ -/** - 문제 이해 - - 주어진 숫자열에 여러 숫자가 주어지고, - - 두 번 이상 동일한 숫자가 나온다면 true, 그렇지 않다면 false - - 문제 해결을 위한 의식의 흐름 - - 맨처음에는 숫자 범위가 작다면 count를 위한 array를 생각 - - 숫자 범위가 int 범위 가까이 된다면, 시공간 복잡도 초과 - - 기록하고, query 가 빠르게 이뤄지는 자료구조 필요 - - count를 위해 숫자를 굳이 저장할 필요가 없고, 존재하는지만 확인하면 된다. - -> Set 자료구조 필요성 - - 시공간 복잡도 - - nums의 length를 N 이라 하면, - - 시간복잡도 : O(N) - N번 순회, 매 query별로 이론상 O(1) - - 공간복잡도 : O(N) - -*/ +// 문제 이해 +// - 주어진 숫자열에 여러 숫자가 주어지고, +// - 두 번 이상 동일한 숫자가 나온다면 true, 그렇지 않다면 false +// +// +// 문제 해결을 위한 의식의 흐름 +// - 맨처음에는 숫자 범위가 작다면 count를 위한 array를 생각 +// - 숫자 범위가 int 범위 가까이 된다면, 시공간 복잡도 초과 +// - 기록하고, query 가 빠르게 이뤄지는 자료구조 필요 +// - count를 위해 숫자를 굳이 저장할 필요가 없고, 존재하는지만 확인하면 된다. +// -> Set 자료구조 필요성 +// +// 시공간 복잡도 +// TC: O(N) +// SC: O(N) +// - nums의 length를 N 이라 하면, +// - 시간복잡도 : O(N) - N번 순회, 매 query별로 이론상 O(1) +// - 공간복잡도 : O(N) class Solution { diff --git a/house-robber/namuuCY.java b/house-robber/namuuCY.java index b0e8403fb5..a00cfeea4f 100644 --- a/house-robber/namuuCY.java +++ b/house-robber/namuuCY.java @@ -1,47 +1,50 @@ -class Solution { -/* - -문제 이해 -1. 1자로 주욱 나열되어있는 집 : 인접한다는 것은 index가 1차이 난다는 것 -2. 인접하는 두 집을 연속해서 털면 안된다. -3. 2의 제약조건을 가지고 털 수 있는 돈의 최대 합 - -문제 해결을 위한 의식의 흐름 -- 이거 예전에 백준에서 봤던 문제같음. -- 어떤 한 집을 방문할 때, 앞 집이 털렸을 경우와 털리지 않았을 경우를 모두 고려해야함. -- 맨 처음으로 DP를 생각하게 됨. - - 털렸을 경우와 털리지 않았을 경우의 값을 모두 저장해놔야 할 것으로 생각 - - 2차원 배열 DP를 아래와 같이 정의한다면 - - DP[0-안털었다 or 1-털었다][index] = index번째 집까지 왔을때 훔친 돈의 총합 - 1. 총합이므로 자료형은 int 만으로 충분? long 배열써야하는지? - - nums[i]가 최대 400이고, nums 길이가 100 이하 이므로 int로도 충분 - 2. DP 채워지는건 어떻게? 점화식 - - i번째 집을 방문할 때 - - i번째 집을 턴다고 가정 : i - 1 번째 집은 털지 않은 상태 + 현재 집의 돈 - - i번째 집을 털지 않는다고 가정 : i - 1 번째 집은 털어도 되고, 털지 않아도 됨 두 개중 최댓값 - 3. 이렇게 DP를 정의할 경우, DAG인가? - - i번째 집의 정보는 i-1번째 집의 정보로부터만 오기 때문에 DAG이다. - - 엣지케이스? : - - 맨 처음 index - DP[0][0] = 0 / 0이면 더하지 않고, - DP[0][0] = nums[0] / 1이면 더한다 - - 길이가 1이면? -- 쓰다보니 느낀건데 어차피 이전 집의 값만 필요하니까 굳이 DP를 사용안해도 될 것 같은데? - - 이렇게 하면 array 로 데이터 저장할 필요 X +// TC: O(N) +// SC: O(1) +class Solution { -시공간복잡도 -N : nums의 길이 -- DP 풀이 : - - 시간 복잡도 : O(N) - - 공간 복잡도 : O(N) // N * 2 개만큼 저장해야함. -- DP X 풀이 : - - 시간 복잡도 : O(N) - - 공간 복잡도 : O(1) // 이전 값 2개만 저장하면 됨. +// 문제 이해 +// 1. 1자로 주욱 나열되어있는 집 : 인접한다는 것은 index가 1차이 난다는 것 +// 2. 인접하는 두 집을 연속해서 털면 안된다. +// 3. 2의 제약조건을 가지고 털 수 있는 돈의 최대 합 +// +// 문제 해결을 위한 의식의 흐름 +// - 이거 예전에 백준에서 봤던 문제같음. +// - 어떤 한 집을 방문할 때, 앞 집이 털렸을 경우와 털리지 않았을 경우를 모두 고려해야함. +// - 맨 처음으로 DP를 생각하게 됨. +// - 털렸을 경우와 털리지 않았을 경우의 값을 모두 저장해놔야 할 것으로 생각 +// - 2차원 배열 DP를 아래와 같이 정의한다면 +// - DP[0-안털었다 or 1-털었다][index] = index번째 집까지 왔을때 훔친 돈의 총합 +// 1. 총합이므로 자료형은 int 만으로 충분? long 배열써야하는지? +// - nums[i]가 최대 400이고, nums 길이가 100 이하 이므로 int로도 충분 +// 2. DP 채워지는건 어떻게? 점화식 +// - i번째 집을 방문할 때 +// - i번째 집을 턴다고 가정 : i - 1 번째 집은 털지 않은 상태 + 현재 집의 돈 +// - i번째 집을 털지 않는다고 가정 : i - 1 번째 집은 털어도 되고, 털지 않아도 됨 두 개중 최댓값 +// 3. 이렇게 DP를 정의할 경우, DAG인가? +// - i번째 집의 정보는 i-1번째 집의 정보로부터만 오기 때문에 DAG이다. +// - 엣지케이스? : +// - 맨 처음 index +// DP[0][0] = 0 / 0이면 더하지 않고, +// DP[0][0] = nums[0] / 1이면 더한다 +// - 길이가 1이면? +// - 쓰다보니 느낀건데 어차피 이전 집의 값만 필요하니까 굳이 DP를 사용안해도 될 것 같은데? +// - 이렇게 하면 array 로 데이터 저장할 필요 X +// +// +// 시공간복잡도 +// N : nums의 길이 +// - DP 풀이 : +// - 시간 복잡도 : O(N) +// - 공간 복잡도 : O(N) // N * 2 개만큼 저장해야함. +// - DP X 풀이 : +// - 시간 복잡도 : O(N) +// - 공간 복잡도 : O(1) // 이전 값 2개만 저장하면 됨. +// -*/ -/* DP 풀이 +/* + DP 풀이 public int rob(int[] nums) { int[][] DP = new int[2][nums.length]; DP[1][0] = nums[0]; From 6c52d98e11a8fdd9506babba1013ae0648e782d0 Mon Sep 17 00:00:00 2001 From: namucy Date: Sat, 27 Jun 2026 21:35:46 +0900 Subject: [PATCH 04/12] two sum solution --- two-sum/namuuCY.java | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 two-sum/namuuCY.java diff --git a/two-sum/namuuCY.java b/two-sum/namuuCY.java new file mode 100644 index 0000000000..fe4af0ddb8 --- /dev/null +++ b/two-sum/namuuCY.java @@ -0,0 +1,25 @@ +// 문제 풀이 흐름 +// target이 고정되어있고, 이 target에서 현재 값을 뺀게 존재하는지를 확인해야함. +// 존재한다면, 그 값의 인덱스를 바로 알아야 함. +// hashmap을 사용 + +// N = nums.length 라 하면 +// 시간복잡도 : O(N) +// 공간복잡도 : O(N) + +class Solution { + public int[] twoSum(int[] nums, int target) { + Map numberCount = new HashMap<>(); + + for (int i = 0 ; i < nums.length; i ++) { + int val = target - nums[i]; + if (numberCount.containsKey(val)) { + return new int[]{i, numberCount.get(val)}; + } + + numberCount.put(nums[i], i); + } + + return null; + } +} From b086edce5d5ef2f165efaf35277b1b448ef1c8c7 Mon Sep 17 00:00:00 2001 From: namucy Date: Sat, 27 Jun 2026 21:55:03 +0900 Subject: [PATCH 05/12] top k frequent elements solution --- top-k-frequent-elements/namuuCY.java | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 top-k-frequent-elements/namuuCY.java diff --git a/top-k-frequent-elements/namuuCY.java b/top-k-frequent-elements/namuuCY.java new file mode 100644 index 0000000000..acd4f14672 --- /dev/null +++ b/top-k-frequent-elements/namuuCY.java @@ -0,0 +1,32 @@ +// 문제 풀이 흐름 +// 각 숫자가 몇개가 나왔는지 계속해서 저장하고, 바로 확인할 수 있는 자료구조가 필요 +// -> HashMap + +// N = nums.length 라 할때 +// 시간복잡도 : O(NlogN) +// 공간복잡도 : O(N) + +class Solution { + public int[] topKFrequent(int[] nums, int k) { + Map numberCount = new HashMap<>(); + + for (int number : nums) { + int countOfCurrentNumber = numberCount.getOrDefault(number, 0); + numberCount.put(number, countOfCurrentNumber + 1); + } + + List numbers = new ArrayList<>(numberCount.keySet()); + + numbers.sort((first, second) -> + Integer.compare(numberCount.get(second), numberCount.get(first)) + ); + + int[] answer = new int[k]; + + for (int i = 0 ; i < k ; i ++) { + answer[i] = numbers.get(i); + } + + return answer; + } +} From 1c2fc5b882ce889518fe15f86597c8c55b1c273b Mon Sep 17 00:00:00 2001 From: namucy Date: Sat, 27 Jun 2026 22:10:00 +0900 Subject: [PATCH 06/12] longest consecutive sequence solution --- longest-consecutive-sequence/namuuCY.java | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 longest-consecutive-sequence/namuuCY.java diff --git a/longest-consecutive-sequence/namuuCY.java b/longest-consecutive-sequence/namuuCY.java new file mode 100644 index 0000000000..4e4cb38f9c --- /dev/null +++ b/longest-consecutive-sequence/namuuCY.java @@ -0,0 +1,33 @@ +// 문제 풀이 흐름 +// 오름차순 sort 후에 현재 보고 있는 숫자가 이전 숫자와 +// 같으면 count 유지 +// 1차이나면 count 증가 +// 이외에는 count 초기화 및 이전 count 최댓값 비교 + +// N = nums.length 라 할때 +// 시간복잡도 : O(N logN) +// 공간복잡도 : O(N) + +class Solution { + public int longestConsecutive(int[] nums) { + Arrays.sort(nums); + + if (nums.length == 0) return 0; + + int maxSequenceLength = 0; + int currentLength = 1; + + for (int i = 1 ; i < nums.length; i ++) { + if (nums[i] == nums[i - 1]) continue; + if (nums[i] == nums[i - 1] + 1) { + currentLength ++; + continue; + } + + maxSequenceLength = Math.max(maxSequenceLength, currentLength); + currentLength = 1; + } + + return Math.max(maxSequenceLength, currentLength); + } +} From a4c5df7e5215996dc57a67f6ad09617327d8b2e3 Mon Sep 17 00:00:00 2001 From: namucy Date: Wed, 1 Jul 2026 22:47:49 +0900 Subject: [PATCH 07/12] climbing-stairs solution --- climbing-stairs/namuuCY.java | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 climbing-stairs/namuuCY.java diff --git a/climbing-stairs/namuuCY.java b/climbing-stairs/namuuCY.java new file mode 100644 index 0000000000..86bc29cf77 --- /dev/null +++ b/climbing-stairs/namuuCY.java @@ -0,0 +1,28 @@ +// 문제 풀이 흐름 +// 누가봐도 점화식 -> DP 문제이다. +// 자세히 보니 피보나치수열 같음 +// 1,2번쨰 항일때만 주의해서 풀자. + +// n에 대해서 +// 시간복잡도 : O(n) +// 공간복잡도 : O(1) + +class Solution { + public int climbStairs(int n) { + if (n == 1) return 1; + if (n == 2) return 2; + + // 3 = 2 * [1] + [2] + // 4 = 2 * [2] + [3] + int doublePrev = 0; + int prev = 1; + int current = 2; + + for (int i = 3 ; i <= n ; i++ ) { + doublePrev = prev; + prev = current; + current = doublePrev + prev; + } + return current; + } +} From 36f8adededb7b323f015696198573eb2c25f00c2 Mon Sep 17 00:00:00 2001 From: namucy Date: Wed, 1 Jul 2026 22:51:00 +0900 Subject: [PATCH 08/12] valid-anagram solution --- valid-anagram/namuuCY.java | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 valid-anagram/namuuCY.java diff --git a/valid-anagram/namuuCY.java b/valid-anagram/namuuCY.java new file mode 100644 index 0000000000..397015170a --- /dev/null +++ b/valid-anagram/namuuCY.java @@ -0,0 +1,29 @@ +// 문제 풀이 흐름 +// 아나그램 : 글자 빈도가 같으면 항상 아나그램 관계 +// 가장 먼저 : 전체 글자수가 같은지 비교 +// 그 다음 -> 알파벳 별로 빈도수가 같은지 비교 + +// n = max(s의 길이, t의 길이)라고 했을때 +// 시간복잡도 : O(n) +// 공간복잡도 : O(1) + +class Solution { + public boolean isAnagram(String s, String t) { + int[] sCount = new int[26]; + int[] tCount = new int[26]; + + if (s.length() != t.length()) return false; + + for (int i = 0 ; i < s.length() ; i++) { + sCount[s.charAt(i) - 'a'] ++; + tCount[t.charAt(i) - 'a'] ++; + } + + for (int i = 0 ; i < 26 ; i++) { + if (sCount[i] == tCount[i]) continue; + return false; + } + + return true; + } +} From d91fc7e22c144d74c56a1fbf900a5db73ec292fe Mon Sep 17 00:00:00 2001 From: namucy Date: Wed, 1 Jul 2026 22:57:57 +0900 Subject: [PATCH 09/12] product of array except self solution --- product-of-array-except-self/namuuCY.java | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 product-of-array-except-self/namuuCY.java diff --git a/product-of-array-except-self/namuuCY.java b/product-of-array-except-self/namuuCY.java new file mode 100644 index 0000000000..1d836b5325 --- /dev/null +++ b/product-of-array-except-self/namuuCY.java @@ -0,0 +1,48 @@ +// 문제 풀이 흐름 : +// 전체의 합에서 자기 자신만 뺀것을 생각하듯이, 전체의 곱에서 자기 자신만 나눈 것을 생각하자 +// 이때, 중요한 것은 integer overflow와 0이 여러번 나올 떄 예외처리 +// integer overflow : 문제에서는 답이 32 bit integer 라고 했지, 그 과정에서 생길 수 있는 곱들이 int범위라고 단정지을 수 없음 +// 0의 개수에 따라 다르게 계산 : +// 0이 없을 때 : 상관없음. +// 1개만 있을 때 : 0인 곳에만 product 기입 +// 2개만 있을 때 : 모두 0이 된다. + +// n = nums.length 라 할때 +// 시간복잡도 : O(n) +// 공간복잡도 : O(n) + + +class Solution { + public int[] productExceptSelf(int[] nums) { + int zeros = 0; + long totalProduct = 1; + + for (int number : nums) { + if (number == 0) { + zeros ++; + } + totalProduct *= number; + } + + int[] answer = new int[nums.length]; + + if (zeros == 0) { + for (int i = 0 ; i < nums.length; i ++ ) { + answer[i] = (int) (totalProduct / nums[i]); + } + } else if (zeros == 1) { + int nonZeroProduct = 1; + int zeroIdx = -1; + for (int i = 0 ; i < nums.length; i ++ ) { + if (nums[i] == 0) { + zeroIdx = i; + continue; + } + nonZeroProduct *= nums[i]; + } + answer[zeroIdx] = nonZeroProduct; + } + + return answer; + } +} From 6f9c2e227ad15815246f43f0173bd0013ecaf02c Mon Sep 17 00:00:00 2001 From: namucy Date: Wed, 1 Jul 2026 23:58:01 +0900 Subject: [PATCH 10/12] validate binary search tree solution --- validate-binary-search-tree/namuuCY.java | 62 ++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 validate-binary-search-tree/namuuCY.java diff --git a/validate-binary-search-tree/namuuCY.java b/validate-binary-search-tree/namuuCY.java new file mode 100644 index 0000000000..86d1b00987 --- /dev/null +++ b/validate-binary-search-tree/namuuCY.java @@ -0,0 +1,62 @@ +// 문제 풀이 흐름 +// 기억하기로는 트리 순회 하는 방식이 몇 가지 있던거로 기억하는데 +// 왼쪽 자식 -> 부모 -> 오른쪽 자식 이 방식으로 순회하는 방식을 사용해야함. +// 그렇게 순회하도록 한 뒤, 순서대로 확인하는데 숫자가 증가하지 않는다면 invalid +// 순회 아이디어 : 재귀를 이용 + 이전 노드 방문 값을 항상 저장 +// 맨 처음 노드 방문 값은 -2^32 로 하자 -> 맨 왼쪽 노드는 항상 그 다음이 되도록 +// param : 현재 노드 +// 왼쪽 자식이 있다면? 왼쪽 노드 방문, +// 없으면 무시 +// 현재 노드 값 valid한지 +// 오른쪽 자식이 있다면? 오른쪽 노드 방문 + +// n = node 갯수라고 한다면 +// 시간복잡도 : O(n) +// 공간복잡도 : O(1) + + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + + long currentValue = -(1L << 33); + + public boolean isValidBST(TreeNode root) { + return visitNode(root); + } + + + private boolean visitNode(TreeNode node) { + // 왼쪽 자식 + if (node.left != null) { + boolean isValid = visitNode(node.left); + if (!isValid) return false; + } + + // 현재 노드 + if (currentValue >= node.val) return false; + currentValue = node.val; + + // 오른쪽 자식 + if (node.right != null) { + boolean isValid = visitNode(node.right); + if (!isValid) return false; + } + + return true; + } +} From 455e278977c5e5b3ee6be9e73c014fec63a45228 Mon Sep 17 00:00:00 2001 From: namucy Date: Thu, 2 Jul 2026 01:45:13 +0900 Subject: [PATCH 11/12] 3 sum solution --- 3sum/namuuCY.java | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 3sum/namuuCY.java diff --git a/3sum/namuuCY.java b/3sum/namuuCY.java new file mode 100644 index 0000000000..a7692164a2 --- /dev/null +++ b/3sum/namuuCY.java @@ -0,0 +1,67 @@ +// 문제 풀이 흐름 +// 세 개의 변수. 만약 brute-force(3중 for문 -> 3000 ^ 3 이어서 시간복잡도 너무 높음.) -> 어떤 한 값을 고정해서 변수를 줄이자. +// 그러면 나머지 두 개는? 투 포인터 같은거 쓰면 안되나? +// 근데 중복되는 경우에 대해서 어떻게 고려함? +// 중복되는 경우가 너무 많다.. +// 우선 정렬 먼저 -> 이후 하나 고정하고 나머지 투포인터 생각 +// 중복되는거 생각나는대로, 음... + +// N = nums.length라 할때 +// 시간 복잡도 정렬 + for문 1개 * 길이 N 투포인터 +// = O(N^2) +// 공간 복잡도 두 가지로 설명 +// - Arrays.sort() 로 정렬 시 필요한 추가 공간(or 스택)을 따질 경우 : O(log N) +// - 따지지 않을 경우 : O(1) + +class Solution { + + int[] nums; + List> answer = new ArrayList<>(); + + public List> threeSum(int[] nums) { + this.nums = nums; + // 원본 배열 정렬 + Arrays.sort(nums); + + for (int fixed = 0; fixed < nums.length - 2; fixed++) { + // fixed가 이전의 값과 동일할 경우 skip + if (fixed > 0 && nums[fixed] == nums[fixed - 1]) continue; + + // fixed가 양수이면 뒤에도 무조건 양수이므로 break + if (nums[fixed] > 0) break; + + searchByTwoPointer(fixed); + } + + return answer; + } + + private void searchByTwoPointer(int fixedIdx) { + int leftIdx = fixedIdx + 1; + int rightIdx = nums.length - 1; + + while (leftIdx < rightIdx) { + int sum = nums[fixedIdx] + nums[leftIdx] + nums[rightIdx]; + + if (sum == 0) { + answer.add(Arrays.asList( + nums[fixedIdx], + nums[leftIdx], + nums[rightIdx] + )); + + // 중복된것에 대해서 조정해줘야함. + + leftIdx ++; + rightIdx --; + + while (leftIdx < rightIdx && nums[leftIdx] == nums[leftIdx - 1]) leftIdx++; + while (leftIdx < rightIdx && nums[rightIdx] == nums[rightIdx + 1]) rightIdx--; + } else if (sum < 0) { + leftIdx ++; + } else { + rightIdx --; + } + } + } +} From afbe1e011023b64aa0b44b1945401a0b32d13a22 Mon Sep 17 00:00:00 2001 From: namucy Date: Thu, 2 Jul 2026 16:51:16 +0900 Subject: [PATCH 12/12] product of array except self solution ii --- product-of-array-except-self/namuuCY.java | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/product-of-array-except-self/namuuCY.java b/product-of-array-except-self/namuuCY.java index 1d836b5325..e74979211a 100644 --- a/product-of-array-except-self/namuuCY.java +++ b/product-of-array-except-self/namuuCY.java @@ -13,7 +13,36 @@ class Solution { + + static { + Solution warmup = new Solution(); + for (int i = 0; i < 500; ++i) { + warmup.productExceptSelf(new int[2]); + } + } + + public int[] productExceptSelf(int[] nums) { + int[] answer = new int[nums.length]; + + Arrays.fill(answer, 1); + + int leftProduct = 1; + for (int i = 0 ; i < nums.length - 1; i ++) { + leftProduct *= nums[i]; + answer[i + 1] *= leftProduct; + } + + int rightProduct = 1; + for (int i = nums.length - 1 ; i > 0 ; i --) { + rightProduct *= nums[i]; + answer[i - 1] *= rightProduct; + } + + return answer; + } + + public int[] prevSubmission(int[] nums) { int zeros = 0; long totalProduct = 1;