Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions clone-graph/JeonJe.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

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)

피드백: 깊은 복사를 위해 맵에 원래 노드와 복제 노드를 매핑하고, 각 노드의 이웃을 재귀적으로 복제한다. 이미 복제된 노드는 재방문 시 중복 생성을 방지한다.

개선 제안: 현재 구현이 적절해 보입니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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;
}
}
20 changes: 20 additions & 0 deletions longest-common-subsequence/JeonJe.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

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]을 구한다. 메모리 사용은 두 문자열의 길이의 곱에 비례한다.

개선 제안: 현재 구현이 적절해 보입니다.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

공간에서 좀 더 최적화가 가능합니다. 참고하세요

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dp[i][j]가 i행과 i+1행만 참조하기 때문에, 한 배열로 제자리 덮어쓰면서 대각선 값만 변수로 넘기면 O(min(m, n))로 가능하겠네요. 감사합니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// 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];
}

}
29 changes: 29 additions & 0 deletions longest-repeating-character-replacement/JeonJe.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

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)

피드백: 두 포인터와 알파벳 카운트 배열을 이용해 윈도우 내 최댓 등장 문자 수를 유지한다. 각 단계에서 상한 조건을 확인하고 필요 시 왼쪽 포인터를 한 칸 이동한다.

개선 제안: 현재 구현이 적절해 보입니다.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

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)

피드백: 문자 빈도 배열을 유지하고 윈도우의 크기를 확장하며 필요한 경우 왼쪽 포인터를 이동시킨다. 최댓값 계산은 상수 배열에서의 최대를 매 반복에서 갱신해도 된다.

개선 제안: 현재 구현이 적절해 보입니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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';
}

}
14 changes: 14 additions & 0 deletions reverse-bits/JeonJe.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

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비트 순회를 통해 비트를 뒤집으므로 시간 복잡도는 상수 시간에 가깝고 공간도 상수이다.

개선 제안: 현재 구현이 적절해 보입니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
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;
}
}
Loading