[JeonJe] WEEK 08 Solutions - #2812
Conversation
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
reverse-bits/JeonJe.java
import java.util.*;
// TC: O(1)
// SC: O(1)
class Solution {
public int reverseBits(int n) {
int answer = 0;
for (int i = 0; i < 32; i++) {
int bitFlag = (n >> i) & 1;
answer += (bitFlag << (31 - i));
}
return answer;
}
}- 패턴: Bit Manipulation
- 설명: 주어진 코드는 비트를 하나씩 추출하고 위치를 반전시키는 방식으로 정수를 뒤집는다. 비트 연산과 시프트를 활용한 저수준 연산 패턴으로 Bit Manipulation에 해당한다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(1) | O(32) | ❌ |
| Space | O(1) | O(1) | ✅ |
피드백: 고정된 32비트 순회를 통해 비트를 뒤집으므로 시간 복잡도는 상수 시간에 가깝고 공간도 상수이다.
개선 제안: 현재 구현이 적절해 보입니다.
📊 JeonJe 님의 학습 현황이번 주 제출 문제
누적 학습 요약
문제 풀이 현황
🤖 이 댓글은 GitHub App을 통해 자동으로 작성되었습니다. 🔢 API 사용량 (gpt-5-nano)
|
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
longest-repeating-character-replacement/JeonJe.java
import java.util.*;
// TC: O(n)
// SC: O(1)
class Solution {
public int characterReplacement(String s, int k) {
int[] counts = new int[26];
int left = 0;
for (int right = 0; right < s.length(); right++) {
counts[toAlphabetIndex(s.charAt(right))]++;
int windowLength = right - left + 1;
if (windowLength - countMostFrequent(counts) > k) {
counts[toAlphabetIndex(s.charAt(left))]--;
left++;
}
}
return s.length() - left;
}
private int toAlphabetIndex(char c) {
return c - 'A';
}
private int countMostFrequent(int[] counts) {
int max = 0;
for (int count : counts) {
max = Math.max(max, count);
}
return max;
}
}- 패턴: Sliding Window, Greedy
- 설명: 문자 교체로 최장 부분 문자열을 만들 때, 현재 윈도우 크기에서 가장 빈도 높은 문자 수를 활용해 필요한 교체 수를 판단하고 윈도우를 확장/축소하는 방식으로 풀이됩니다. 이는 고정된 윈도우 크기를 조정하며 최적 부분 문자열을 찾는 Sliding Window 및 부분 최적화의 아이디어를 활용한 Greedy 패턴에 속합니다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n) | O(n) | ✅ |
| Space | O(1) | O(1) | ✅ |
피드백: 두 포인터와 알파벳 카운트 배열을 이용해 윈도우 내 최댓 등장 문자 수를 유지한다. 각 단계에서 상한 조건을 확인하고 필요 시 왼쪽 포인터를 한 칸 이동한다.
개선 제안: 현재 구현이 적절해 보입니다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
longest-repeating-character-replacement/JeonJe.java
import java.util.*;
// TC: O(n)
// SC: O(1)
class Solution {
public int characterReplacement(String s, int k) {
int[] counts = new int[26];
int left = 0;
for (int right = 0; right < s.length(); right++) {
counts[toAlphabetIndex(s.charAt(right))]++;
int windowLength = right - left + 1;
int mostFreq = Arrays.stream(counts).max().getAsInt();
//바꿀 대상이 k 횟수보다 크면, left을 옮김
if (windowLength - mostFreq > k) {
counts[toAlphabetIndex(s.charAt(left))]--;
left++;
}
}
return s.length() - left;
}
private int toAlphabetIndex(char c) {
return c - 'A';
}
}- 패턴: Sliding Window, Hash Map / Hash Set, Greedy
- 설명: 문자 배열의 부분 문자열을 윈도우 크기로 확장/수축하며 가장 빈도 높은 문자의 개수를 이용해 필요한 변경 수를 판단하는 슬라이딩 윈도우 패턴이다. 빈도 배열을 통해 각 창에서의 상태를 빠르게 갱신하고, 조건을 만족할 때까지 윈도우를 움직여 최적 값을 구한다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n) | O(n) | ✅ |
| Space | O(1) | O(1) | ✅ |
피드백: 문자 빈도 배열을 유지하고 윈도우의 크기를 확장하며 필요한 경우 왼쪽 포인터를 이동시킨다. 최댓값 계산은 상수 배열에서의 최대를 매 반복에서 갱신해도 된다.
개선 제안: 현재 구현이 적절해 보입니다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
clone-graph/JeonJe.java
import java.util.*;
// TC: O(V + E)
// SC: O(V)
class Solution {
public Node cloneGraph(Node node) {
return deepCopy(node, new HashMap<>());
}
private Node deepCopy(Node node, Map<Node, Node> cloned) {
if (node == null) {
return null;
}
if (cloned.containsKey(node)) {
return cloned.get(node);
}
Node clonedNode = new Node(node.val);
cloned.put(node, clonedNode);
for (Node neighbor : node.neighbors) {
clonedNode.neighbors.add(deepCopy(neighbor, cloned));
}
return clonedNode;
}
}- 패턴: Depth-First Search, Hash Map / Hash Set
- 설명: 그래프를 깊이 우선으로 순회하며 각 노드를 복제하고, 이미 복제된 노드는 맵에서 재사용한다. 해시 맵으로 중복 방지를 통해 사이클이 있는 그래프도 안전하게 복제한다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(V + E) | O(N + E) | ❌ |
| Space | O(V) | O(N) | ❌ |
피드백: 깊은 복사를 위해 맵에 원래 노드와 복제 노드를 매핑하고, 각 노드의 이웃을 재귀적으로 복제한다. 이미 복제된 노드는 재방문 시 중복 생성을 방지한다.
개선 제안: 현재 구현이 적절해 보입니다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
longest-common-subsequence/JeonJe.java
// TC: O(m * n)
// SC: O(m * n)
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int[][] dp = new int[text1.length() + 1][text2.length() + 1];
for (int i = text1.length() - 1; i >= 0; i--) {
for (int j = text2.length() - 1; j >= 0; j--) {
dp[i][j] = text1.charAt(i) == text2.charAt(j) ?
1 + dp[i + 1][j + 1] :
Math.max(dp[i + 1][j], dp[i][j + 1]);
}
}
return dp[0][0];
}
}- 패턴: Dynamic Programming
- 설명: 두 문자열의 공통 부분수열 길이를 DP 테이블로 역방향 채우는 전형적인 DP 문제로, 부분문제의 해를 이용해 최종 해를 구한다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(m * n) | O(n * m) | ❌ |
| Space | O(m * n) | O(n * m) | ❌ |
피드백: 두 문자열의 남은 부분 문제를 좌상단부터 채우는 대신 역방향으로 채워서 최종 dp[0][0]을 구한다. 메모리 사용은 두 문자열의 길이의 곱에 비례한다.
개선 제안: 현재 구현이 적절해 보입니다.
There was a problem hiding this comment.
공간에서 좀 더 최적화가 가능합니다. 참고하세요
There was a problem hiding this comment.
dp[i][j]가 i행과 i+1행만 참조하기 때문에, 한 배열로 제자리 덮어쓰면서 대각선 값만 변수로 넘기면 O(min(m, n))로 가능하겠네요. 감사합니다!
답안 제출 문제
작성자 체크 리스트
In Review로 설정해주세요.검토자 체크 리스트
Important
본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!