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
33 changes: 33 additions & 0 deletions coin-change/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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Dynamic Programming, Backtracking
  • 설명: 메모이제이션을 이용한 재귀적 탐색으로 금액(target)을 만드는 최소 동전 수를 계산한다. 중복 하위 문제를 저장하고 재귀적으로 풀이하여 최적해를 도출하는 DP 패턴에 해당한다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(n * amount) O(amount * k)
Space O(amount) O(amount)

피드백: 재귀 + 메모이제이션으로 중복 계산을 줄였지만, 최악의 경우 모든 target에 대해 모든 코인을 시도하므로 시간복잡도는 O(amount * k)다.

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

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.

저는 바텀업 방식으로 작성했는데 탑다운으로 풀어주셨군요!
coins: [1], amout: 10000이 입력으로 주어졌을 때 재귀 스택이 10,000까지 깊어질 수 있을 것 같습니다~

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.

아하 조금만 제약 조건의 범위가 늘어나면 스택 오버플로우가 발생할 수 있겠네요.
반복문을 써서 가장 작은 금액 단위부터 채워나가는 식의 바텀업 풀이가 좋아보이긴하네요.

꼼꼼한 리뷰 감사합니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import java.util.*;

// TC: O(n * amount) (n = coins.length)
// SC: O(amount)
class Solution {

private static final int IMPOSSIBLE = Integer.MAX_VALUE;

private int[] memo;

public int coinChange(int[] coins, int amount) {
memo = new int[amount + 1];
Arrays.fill(memo, -1);

int result = minCoins(amount, coins);
return result == IMPOSSIBLE ? -1 : result;
}

private int minCoins(int target, int[] coins) {
if (target == 0) return 0;
if (target < 0) return IMPOSSIBLE;
if (memo[target] != -1) return memo[target];

int best = IMPOSSIBLE;
for (int coin : coins) {
int sub = minCoins(target - coin, coins);
if (sub != IMPOSSIBLE) {
best = Math.min(best, sub + 1);
}
}
return memo[target] = best;
}
}
24 changes: 24 additions & 0 deletions find-minimum-in-rotated-sorted-array/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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Binary Search
  • 설명: 중간 값을 기준으로 영역을 반으로 나누며 최소 원소 위치를 찾는 이진 탐색 패턴으로, 회전된 정렬 배열에서 부분 정렬 여부를 판단해 탐색 범위를 축소합니다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(log n) O(log 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.

저도 동일하게 이진 탐색하도록 풀었습니다. 잘 봤습니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import java.util.*;

// TC: O(log n)
// SC: O(1)
class Solution {
public int findMin(int[] nums) {

int lowIndex = 0;
int highIndex = nums.length - 1;

while(lowIndex < highIndex) {
int midIndex = (lowIndex + highIndex) / 2;

//오른 부분이 정렬 되지 않음 = 왼쪽 부분은 정렬됨
if(nums[midIndex] > nums[highIndex]) {
lowIndex = midIndex + 1;
} else {
//오른쪽 부분이 정렬 됨 = 왼쪽 부분을 봐야함
highIndex = midIndex;
}
}
return nums[lowIndex];
}
}
15 changes: 15 additions & 0 deletions maximum-depth-of-binary-tree/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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Depth-First Search, Binary Search, Divine Pattern?
  • 설명: 가장 깊이를 재는 재귀 탐색으로 왼쪽/오른쪽 자식을 먼저 탐색하는 DFS 패턴이며, 트리의 각 노드를 방문하며 최대 깊이를 갱신합니다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(n) O(n)
Space O(h) O(h)

피드백: 트리의 모든 노드를 방문하며 깊이 우선으로 탐색한다.

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

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.

직관적이고 간결한 풀이 잘 봤습니다 👍

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import java.util.*;

// TC: O(n)
// SC: O(h)
class Solution {
public int maxDepth(TreeNode root) {
return calMaxDepth(root);
}

// 현재까지 최대 깊이는 Math.max(왼쪽 서브노드 최대 깊이 , 오른쪽 서브노드 최대깊이) + 1
private int calMaxDepth(TreeNode node) {
if (node == null) return 0;
return Math.max(calMaxDepth(node.left), calMaxDepth(node.right)) + 1;
}
}
31 changes: 31 additions & 0 deletions merge-two-sorted-lists/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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Two Pointers, Merge Sort
  • 설명: 리스트를 순차적으로 비교하며 작은 값을 차례로 연결하는 구간은 Two Pointers 패턴의 전형이며, 두 정렬된 리스트를 합치는 동작은 분할된 부분 배열을 합치는 개념으로 해석할 수 있습니다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(n+m) O(n + m)
Space O(n+m) 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.

ListNode 할당하는 로직을 조금 수정해서 공간 복잡도를 O(1)로 개선해보면 좋을 것 같습니다!

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.

노드를 새로 만드는게 아니라, 이미 있는 list1, list2 노드를 이어 붙여주는 방식으로 최적화가 가능하겠네요!
생각 못했던 부분인데 좋은 리뷰 감사합니다!!

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import java.util.*;

// TC: O(n+m)
// SC: O(n+m)
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy = new ListNode(0);
ListNode tail = dummy;

while (list1 != null && list2 != null) {
if (list1.val > list2.val) {
tail.next = new ListNode(list2.val);
list2 = list2.next;
} else {
tail.next = new ListNode(list1.val);
list1 = list1.next;
}
tail = tail.next;
}

if (list1 != null) {
tail.next = list1;
}

if (list2 != null) {
tail.next = list2;
}

return dummy.next;
}
}
58 changes: 58 additions & 0 deletions word-search/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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Depth-First Search, Backtracking
  • 설명: 이 코드는 보드에서 인접 문자로 단서를 따라 탐색하며 단서를 맞출 때마다 이전 선택을 되돌리는 백트래킹 기법을 사용한다. DFS로 방향을 따라 깊이 탐색하고, 실패 시 되돌아가면서 다른 경로를 시도한다.

📊 시간/공간 복잡도 분석

복잡도
Time O(m * n * 4^L)
Space O(L)

피드백: 각 위치에서 방향마다 DFS를 수행하고 방문 추적 배열로 중복을 방지한다.

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

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

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.

dx, dy로 포지션을 미리 할당해놓고 쓰니까 깔끔하네요. 잘 봤습니다!!

visited 배열을 선언하지 않도록해서 공간 복잡도를 O(L)로 최적화를 해보는 것도 좋을 것 같습니다 🔥

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.

무의식적으로 visited 배열을 사용해서 dfs/bfs 를 풀고 있었는데 사용하지 않는 방식도 고민을 해봐야겠네요
감사합니다!!

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import java.util.*;

// TC: O(m * n * 4^L)
// SC: O(m * n)
class Solution {

private char[][] board;
private int m, n;
private boolean[][] visited;
private char[] word;
private static final int[] dx = {-1, 1, 0, 0};
private static final int[] dy = {0, 0, -1, 1};


public boolean exist(char[][] board, String word) {
this.board = board;
this.word = word.toCharArray();
this.n = board.length;
this.m = board[0].length;
this.visited = new boolean[n][m];

for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (dfs(i, j, 0)) {
return true;
}
}
}
return false;
}

private boolean dfs(int x, int y, int wordIndex) {
if (board[x][y] != word[wordIndex] || visited[x][y]) {
return false;
}
if (wordIndex == word.length - 1) {
return true;
}

visited[x][y] = true;

for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 0 || nx >= n || ny < 0 || ny >= m) {
continue;
}

if (board[nx][ny] == word[wordIndex + 1] && !visited[nx][ny]) {
if (dfs(nx, ny, wordIndex + 1)) {
return true;
}
}
}
visited[x][y] = false;
return false;
}
}
Loading