From 52b6d7f436bf1980f71ae610373d53c559269e61 Mon Sep 17 00:00:00 2001 From: danny Date: Fri, 10 Jul 2026 14:51:05 +0900 Subject: [PATCH 1/7] 0125-valid-palindrome --- valid-palindrome/dahyeong-yun.java | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 valid-palindrome/dahyeong-yun.java diff --git a/valid-palindrome/dahyeong-yun.java b/valid-palindrome/dahyeong-yun.java new file mode 100644 index 0000000000..7166312774 --- /dev/null +++ b/valid-palindrome/dahyeong-yun.java @@ -0,0 +1,43 @@ +/** + * [풀이 개요] + * - 시간복잡도 : O(n) + * - 공간복잡도 : O(1) + */ +class Solution { + /** + * [문제 풀이 아이디어] + * - 주어진 문자열의 길이가 최대 10^5 이므로 10^8 까지 통과할 수 있다고 가정할 때, 시간복잡도는 O (n log n)까지 가능해 보임 + * - 문자열 s의 시작과 끝 인덱스가 각각 x, y 라고 할 때 s[x] == s[y], s[x+1] == s[y-1], s[x+2] == s[y-2], s[x+n] == s[y-n] (n은 문자열 중간 인덱스 까지) 와 같이 검증할 수 있음. + * - 즉 투포인터 형태가 될 수 있어 보임. + * - 다만 알파벳이 아닌 문자는 제외하고 판단해야 하므로 포인터가 정확히 같은 값을 x, y에서 빼는 형태가 될 수는 없고, 비교 대상이 아닌 인덱스를 넘어가서 다음에 판단해야 함. + * - 이렇게 순회할 경우 문자열 길이 n의 1/2 를 순회하므로 시간복잡도는 O(n) 이 됨. + * - 매 char 변수 이외에 추가 공간이 필요치 않으므로 공간복잡도는 O(1) 이 됨. + */ + public boolean isPalindrome(String s) { + int len = s.length(); + if(len == 1) return true; + + int left = 0; + int right = len - 1; + + while(left < right) { + char leftChar = Character.toLowerCase(s.charAt(left)); + char rightChar = Character.toLowerCase(s.charAt(right)); + + // 문자가 아닌 경우 다음 인덱스 확인 + if(!Character.isLetterOrDigit(leftChar)) { + left++; + } else if(!Character.isLetterOrDigit(rightChar)) { + right--; + + // 동일한 경우 다음 인덱스 확인 + } else if(leftChar == rightChar) { + left++; + right--; + } else { + return false; + } + } + return true; + } +} \ No newline at end of file From c831f911bb4e0d44ef7341bfc210d0f62cb93617 Mon Sep 17 00:00:00 2001 From: danny Date: Fri, 10 Jul 2026 14:55:08 +0900 Subject: [PATCH 2/7] add newline --- valid-palindrome/dahyeong-yun.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/valid-palindrome/dahyeong-yun.java b/valid-palindrome/dahyeong-yun.java index 7166312774..f08a079830 100644 --- a/valid-palindrome/dahyeong-yun.java +++ b/valid-palindrome/dahyeong-yun.java @@ -40,4 +40,4 @@ public boolean isPalindrome(String s) { } return true; } -} \ No newline at end of file +} From b453ac3ebcd34323939a94679114fdbd8becdd33 Mon Sep 17 00:00:00 2001 From: danny Date: Fri, 10 Jul 2026 22:27:44 +0900 Subject: [PATCH 3/7] 0053-maximum-subarray --- maximum-subarray/dahyeong-yun.java | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 maximum-subarray/dahyeong-yun.java diff --git a/maximum-subarray/dahyeong-yun.java b/maximum-subarray/dahyeong-yun.java new file mode 100644 index 0000000000..be665220de --- /dev/null +++ b/maximum-subarray/dahyeong-yun.java @@ -0,0 +1,25 @@ +/** + * [풀이 개요] + * - 시간복잡도 : O(n) + * - 공간복잡도 : O(1) + */ +class Solution { + /** + * [문제 풀이 아이디어] + * - 연속된 부분 배열 합의 최대를 구하는 문제. 즉, 카데인 알고리즘을 떠올릴 수 있음 + * - 수 배열을 한번 순회 하므로 시간복잡도는 O(n) + * - 별도 공간 할당이 없으므로 공간복잡도는 O(1) + */ + public int maxSubArray(int[] nums) { + int max = nums[0]; + int current = nums[0]; + + int len = nums.length; + for(int i=1; i Date: Sat, 11 Jul 2026 11:10:30 +0900 Subject: [PATCH 4/7] 0191-number-of-1-bits --- number-of-1-bits/dahyeong-yun.java | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 number-of-1-bits/dahyeong-yun.java diff --git a/number-of-1-bits/dahyeong-yun.java b/number-of-1-bits/dahyeong-yun.java new file mode 100644 index 0000000000..d18239cf49 --- /dev/null +++ b/number-of-1-bits/dahyeong-yun.java @@ -0,0 +1,46 @@ +/** + * [풀이 개요] + * - 시간복잡도 : O(1) + * - 공간복잡도 : O(1) + */ +class Solution { + public int hammingWeight(int n) { + return Integer.bitCount(n); + } + + /** 참고 + @IntrinsicCandidate + public static int bitCount(int i) { + // HD, Figure 5-2 + i = i - ((i >>> 1) & 0x55555555); + i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); + i = (i + (i >>> 4)) & 0x0f0f0f0f; + i = i + (i >>> 8); + i = i + (i >>> 16); + return i & 0x3f; + } + */ + + /** + * [문제 풀이 아이디어] + * - 10진수를 2진수로 표현했을 때 1의 갯 수를 세야함. + * - 10진수를 2로 나눈 몫이 0이 될 때까지 나누고, 각각의 나머지를 역으로 적으면 2진수가 됨. + * - 따라서 각 나눗셈의 나머지가 1인 경우를 카운트 할 수 있음 + * - 진법 변환 예시 + * - 10 % 2 = 5, 0 - 2^0 + * - 5 % 2 = 2, 1 - 2^1 + * - 2 % 2 = 1, 0 - 2^2 + * - 1 % 2 = 0, 1 - 2^3 + * - 10 => 1010 + * - int는 32비트 자료형으로 최대 32번 반복하므로 시간복잡도는 상수시간으로 봐도 무방, O(1) + * - 별도 공간이 유의미한 공간할당을 하고 있지 않으므로 공간복잡도는 0(1) + */ + public int hammingWeight(int n) { + int count = 0; + while(n > 0) { + count += n % 2; + n /= 2; + } + return count; + } +} From 2cb2b3d4fb365a57c5d016495ce5abbe858c1535 Mon Sep 17 00:00:00 2001 From: danny Date: Sat, 11 Jul 2026 12:08:24 +0900 Subject: [PATCH 5/7] 0091-decode-ways --- decode-ways/dahyeong-yun.java | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 decode-ways/dahyeong-yun.java diff --git a/decode-ways/dahyeong-yun.java b/decode-ways/dahyeong-yun.java new file mode 100644 index 0000000000..b49ae10d43 --- /dev/null +++ b/decode-ways/dahyeong-yun.java @@ -0,0 +1,61 @@ +/** + * [풀이 개요] + * - 시간복잡도 : O(n) + * - 공간복잡도 : O(n) + */ +class Solution { + /** + * [문제 풀이 아이디어] + * - 한 글자로 파싱이 되는 경우의 수와 두 글자로 파싱이 되는 경우 수를 합하면 될 것 같음 + * - 시간복잡도는 각 인덱스를 처음 한번 들린 이 후로는 dp 배열에서 O(1)에 리턴하므로 O(n). + * - 공간복잡도는 문자열 길이 만큼의 dp 배열을 생성하므로 O(n) + */ + public int numDecodings(String s) { + int len = s.length(); + int[] dp = new int[len + 1]; + Arrays.fill(dp, -1); + return count(0, s, len, dp); + } + + /** + * [시뮬레이션] + * Case : 226 + * count(0, 226, {-1,-1,-1}) + * += count(1, 226, {-1,-1,-1}) return 2 / 2 + * += count(2, 226, {-1,-1,-1}) return 1 / 2 2 + * += count(3, 226, {-1,-1,-1}) return 1 / 2 2 6 + * += 0 (4 > limit) + * += count(3, 226, {-1,-1,-1}) return 1 / 2 26 / cashing + * += count(2, 226, {-1,-1,-1}) return 1 / 22 / cashing + * += count(3, 226, {-1,-1,-1}) return 1 / 22 6 / cashing + * = 1 + 2 = 3 + */ + public int count(int start, String s, int limitIndex, int[] dp) { + if(start == limitIndex) { + return 1; + } + // 0으로 시작할 수 없음 + if(s.charAt(start) == '0') { + return 0; + } + + if(dp[start] != -1) { + return dp[start]; + } + + int totalWays = 0; + + if(start + 1 <= limitIndex) { + totalWays += count(start + 1, s, limitIndex, dp); + } + + if(start + 2 <= limitIndex) { + String numStr = s.substring(start, start+2); + if(Integer.parseInt(numStr) <= 26) { + totalWays += count(start + 2, s, limitIndex, dp); + } + } + dp[start] = totalWays; + return totalWays; + } +} \ No newline at end of file From 4e0c9d37e5c0c28ea6ff274df26ecb07f02f37ea Mon Sep 17 00:00:00 2001 From: danny Date: Sat, 11 Jul 2026 12:08:32 +0900 Subject: [PATCH 6/7] add newline --- decode-ways/dahyeong-yun.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decode-ways/dahyeong-yun.java b/decode-ways/dahyeong-yun.java index b49ae10d43..e73cea32a7 100644 --- a/decode-ways/dahyeong-yun.java +++ b/decode-ways/dahyeong-yun.java @@ -58,4 +58,4 @@ public int count(int start, String s, int limitIndex, int[] dp) { dp[start] = totalWays; return totalWays; } -} \ No newline at end of file +} From e77b4366b203a7b59f2ba1bb25594e3afcea0e75 Mon Sep 17 00:00:00 2001 From: danny Date: Sat, 11 Jul 2026 13:11:00 +0900 Subject: [PATCH 7/7] 0039-combination-sum --- combination-sum/dahyeong-yun.java | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 combination-sum/dahyeong-yun.java diff --git a/combination-sum/dahyeong-yun.java b/combination-sum/dahyeong-yun.java new file mode 100644 index 0000000000..955a0bc0c2 --- /dev/null +++ b/combination-sum/dahyeong-yun.java @@ -0,0 +1,60 @@ +/** + * [풀이 개요] + * - 시간복잡도 : O(H(N, M) * M) + * - 공간복잡도 : O(H(N, M) * M) (정답 배열 제외 시 O(M)) + */ +class Solution { + /** + * [문제 풀이 아이디어] + * - candidates 배열의 수를 조합해서 target을 만드는 조합을 중복되는 조합 없이 찾아야 함. + * - 각 원소는 중복이 될 수 있음. 이 때문에 candidates을 여러번 반복해서 찾아야 함. 조합이 되는 배열의 길이가 동적이므로 재귀적으로 확인해야 할 듯. + * - 시공간복잡도의 경우, 중복 조합의 개수를 계산해야 하는 건 알겠는데, 계산이 직관적으로는 이해가 잘 안됨. O(H(N, M) * M) + */ + private List> answer = new ArrayList<>(); + + public List> combinationSum(int[] candidates, int target) { + backtracking(0, 0, target, candidates, new ArrayList<>()); + return answer; + } + + /** + * [시뮬레이션: 인덱스 & Sum 추적] + * 형식: [인덱스 조합] (계산 과정) = 현재Sum + * * * 시작 (Sum = 0) + * ├── [0] (+2) = Sum: 2 + * │ ├── [0, 0] (+2) = Sum: 4 + * │ │ ├── [0, 0, 0] (+2) = Sum: 6 + * │ │ │ └── [0, 0, 0, 0] (+2) = Sum: 8 ❌ (Over 7) + * │ │ └── [0, 0, 1] (+3) = Sum: 7 ★ 정답 [2, 2, 3] + * │ ├── [0, 1] (+3) = Sum: 5 + * │ │ └── [0, 1, 1] (+3) = Sum: 8 ❌ (앞의 2로 못 돌아감) + * │ └── [0, 2] (+6) = Sum: 8 ❌ + * │ + * ├── [1] (+3) = Sum: 3 <-- 이제 이전 인덱스인 0번(값 2)은 영구 제외 + * │ ├── [1, 1] (+3) = Sum: 6 + * │ │ └── [1, 1, 1] (+3) = Sum: 9 ❌ + * │ └── [1, 2] (+6) = Sum: 9 ❌ + * │ + * ├── [2] (+6) = Sum: 6 + * │ └── [2, 2] (+6) = Sum: 12 ❌ + * │ + * └── [3] (+7) = Sum: 7 ★ 정답 [7] + */ + public void backtracking(int start, int sum, int target, int[] candidates, List list) { + if(sum == target) { + answer.add(new ArrayList<>(list)); + return; // 🎯 정답을 찾았으므로 즉시 탈출 (효율성 증가) + } + + if(sum > target) { + return; + } + + // 🎯 i = start 및 재귀 인자 i로 변경하여 주석의 '중복 조합' 로직 완성 + for(int i = start; i < candidates.length; i++) { + list.add(candidates[i]); + backtracking(i, sum + candidates[i], target, candidates, list); + list.remove(list.size() - 1); + } + } +}