[sangbeenmoon] WEEK 08 Solutions - #2820
Conversation
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
clone-graph/sangbeenmoon.java
// Definition for a Node.
import java.util.ArrayList;
import java.util.Map;
/*
class Node {
public int val;
public List<Node> neighbors;
public Node() {
val = 0;
neighbors = new ArrayList<Node>();
}
public Node(int _val) {
val = _val;
neighbors = new ArrayList<Node>();
}
public Node(int _val, ArrayList<Node> _neighbors) {
val = _val;
neighbors = _neighbors;
}
}
*/
class Solution {
// <원본, 복제본>
public Map<Node,Node> map = new HashMap<>();
public Node cloneGraph(Node node) {
if (node == null) {
return null;
}
return dfs(node);
}
public Node dfs(Node origin) {
if (map.containsKey(origin)) {
return map.get(origin);
}
if (origin == null) {
return null;
}
Node copied = new Node(origin.val);
map.put(origin, copied);
for (Node n : origin.neighbors) {
Node neighbor = dfs(n);
copied.neighbors.add(neighbor);
}
return copied;
}
}- 패턴: Depth-First Search, Hash Map / Hash Set
- 설명: 그래프를 깊이 우선으로 순회하며 각 노드를 복제하고, 원래 노드와 복제본 간 매핑을 HashMap으로 저장하여 이미 방문한 노드를 재사용합니다. 순회 시 재귀dfs로 이웃 노드를 방문하며 연결 관계를 재현합니다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(N + E) |
| Space | O(N) |
피드백: 맵으로 원본 노드와 복제본 노드를 매핑해 사이클이 있는 그래프에서도 중복 복제를 방지한다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
longest-common-subsequence/sangbeenmoon.java
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int dp[][] = new int[text1.length()][text2.length()];
for(int i = 0; i < text1.length(); i++){
if (text1.substring(0,i + 1).contains(String.valueOf(text2.charAt(0)))) {
dp[i][0] = 1;
}
}
for(int i = 0; i < text2.length(); i++){
if (text2.substring(0,i + 1).contains(String.valueOf(text1.charAt(0)))) {
dp[0][i] = 1;
}
}
for(int i = 1; i < text1.length(); i++){
for(int j = 1; j< text2.length(); j++){
if(text1.charAt(i) == text2.charAt(j)){
dp[i][j] = dp[i-1][j-1] + 1;
} else {
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}
}
}
return dp[text1.length() - 1][text2.length() - 1];
}
}- 패턴: Dynamic Programming
- 설명: 두 문자열의 최장 공통 부분 수열을 구하기 위해 이차원 DP 테이블을 채우는 방식으로 문제를 해결합니다. 이전 상태의 값을 이용해 현재 상태를 구성하는 전형적인 DP 패턴입니다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n * m) |
| Space | O(n * m) |
피드백: 2차원 DP 배열을 사용해 모든 부분문제 결과를 저장한다.
개선 제안: 경계 초기화와 인덱스 접근을 명확히 하고, 공간을 줄이려면 한 행만 사용하는 방법도 있다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
📊 sangbeenmoon 님의 학습 현황이번 주 제출 문제
누적 학습 요약
문제 풀이 현황
🤖 이 댓글은 GitHub App을 통해 자동으로 작성되었습니다. 🔢 API 사용량 (gpt-5-nano)
|
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
longest-repeating-character-replacement/sangbeenmoon.java
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
class Solution {
Map<Character, Integer> counterMap = new HashMap<>();
public int characterReplacement(String s, int k) {
int left = 0;
int answer = 0;
for (int right = 0; right < s.length(); right++){
if(counterMap.containsKey(s.charAt(right))){
int cnt = counterMap.get(s.charAt(right));
counterMap.put(s.charAt(right), cnt + 1);
}
else {
counterMap.put(s.charAt(right), 1);
}
while (!isCounterOK(k)) {
char l = s.charAt(left);
int cnt = counterMap.get(l);
if (cnt == 1) counterMap.remove(l);
else counterMap.put(l, cnt - 1);
left++;
}
answer = Math.max(answer, right - left + 1);
}
return answer;
}
public boolean isCounterOK(int k) {
int maxCount = 0;
int totalCount = 0;
for (Entry<Character, Integer> entry : counterMap.entrySet()) {
maxCount = Math.max(maxCount, entry.getValue());
totalCount = totalCount + entry.getValue();
}
return totalCount - maxCount <= k;
}
}- 패턴: Two Pointers, Hash Map / Hash Set, Greedy, Sliding Window
- 설명: left와 right 두 포인터로 구간을 확장/축소하며 최적의 길이를 찾는다. 해시 맵으로 문자 빈도수를 추적하고, 전체 길이에서 최다 빈도수를 빼서 허용 횟수 k를 만족하는지 판단한다. 이때 윈도우의 최대 길이를 계속 갱신하므로 슬라이딩 윈도우와 그리디의 결합으로 풀이된다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(AlphabetSize) |
피드백: 윈도우의 크기를 유지하며 최대 빈도 문자를 활용한다.
개선 제안: Counter 갱신 로직을 간결화하고, maxCount를 window 밖에서도 관리하는 방법을 고려해볼 수 있다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
palindromic-substrings/sangbeenmoon.py
class Solution:
def countSubstrings(self, s: str) -> int:
dp = [[0] * (len(s) + 1) for _ in range(len(s) + 1)]
def isPalindrome(start, end) -> bool:
if end - start == 0:
return True
if end - start == 1 :
return s[start] == s[end]
if dp[start][end] == 1:
return True
if dp[start][end] == -1:
return False
if s[start] == s[end]:
return isPalindrome(start+1, end-1)
return False
answer = 0
for i in range(len(s) - 1, -1, -1):
for j in range(i,len(s)):
if isPalindrome(i,j):
dp[i][j] = 1
answer += 1
else:
dp[i][j] = -1
return answer
- 패턴: Dynamic Programming
- 설명: 문자열의 부분 문자열이 회문인지 여부를 DP로 저장해가며(메모이제이션) 중복 계산을 피하고 전체 부분 문자열을 탐색합니다. 주어진 풀이에서 dp 테이블로 회문 여부를 기록하고, 역순으로 시작점과 끝점을 늘려가며 결과를 누적합니다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n^2) |
| Space | O(n^2) |
피드백: isPalindrome 재귀와 DP 표를 섞어 부분 문자열의 회문 여부를 저장한다.
개선 제안: 현재 구현은 Python 구문과 DP 표 초기화가 다소 비효율적일 수 있어, 확정된 확장 방법으로 단순화하는 것을 고려해볼 수 있다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
| if(counterMap.containsKey(s.charAt(right))){ | ||
|
|
||
| int cnt = counterMap.get(s.charAt(right)); | ||
| counterMap.put(s.charAt(right), cnt + 1); | ||
| } | ||
| else { | ||
| counterMap.put(s.charAt(right), 1); | ||
| } | ||
|
|
||
| while (!isCounterOK(k)) { | ||
| char l = s.charAt(left); | ||
| int cnt = counterMap.get(l); | ||
| if (cnt == 1) counterMap.remove(l); | ||
| else counterMap.put(l, cnt - 1); | ||
| left++; | ||
| } | ||
| answer = Math.max(answer, right - left + 1); |
There was a problem hiding this comment.
돌려보니 성능이 좋은 편은 아니라서 조금 더 최적화 시도해보셔도 좋을 거 같습니다.
| public boolean isCounterOK(int k) { | ||
| int maxCount = 0; | ||
| int totalCount = 0; | ||
| for (Entry<Character, Integer> entry : counterMap.entrySet()) { | ||
| maxCount = Math.max(maxCount, entry.getValue()); | ||
| totalCount = totalCount + entry.getValue(); | ||
| } | ||
| return totalCount - maxCount <= k; | ||
| } |
There was a problem hiding this comment.
이쪽에서 오버헤드가 살짝 있어 보이네요. 단순하게 빈도 배열만 사용해보시는 건 어떨까요?
답안 제출 문제
작성자 체크 리스트
In Review로 설정해주세요.검토자 체크 리스트
Important
본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!