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
18 changes: 18 additions & 0 deletions best-time-to-buy-and-sell-stock/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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Greedy, Two Pointers
  • 설명: 최소 가격을 누적 추적하며 현재 가격과의 차이를 통해 가장 큰 이익을 업데이트하는 방식으로, 한 번의 순회로 최적 해를 얻는 그리디 패턴과 문제의 인덱스 순서를 두 포인터처럼 활용하는 형태를 보입니다.

📊 시간/공간 복잡도 분석

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

피드백: 최소 가격을 추적하고 각 날의 이익을 비교해 최댓값을 구하는 표준 풀이이다.

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

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

// TC: O(n)
// SC: O(1)
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
int maxProfit = 0;
int minPrice = prices[0];

for (int sellDay = 1; sellDay < n; sellDay++) {
minPrice = Math.min(minPrice, prices[sellDay]);
maxProfit = Math.max(maxProfit, prices[sellDay] - minPrice);
}
Comment on lines +11 to +14

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.

sellDay 변수명 직관적이어서 좋은 거 같네요


return maxProfit;
}
}
34 changes: 34 additions & 0 deletions encode-and-decode-strings/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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Greedy, Hash Map / Hash Set
  • 설명: 문자열 인코딩/디코딩 방식에서 길이와 구분자를 이용한 순차적 파싱이 핵심이다. 단순한 포맷을 구성하고 이를 재구성하는 흐름은 패턴상 Greedy(탐욕적이진 않지만 직관적 순차 처리)와 문자열 조작/해시 없이도 구현되는 패턴으로 볼 수 있으며, 문자열 길이 정보를 이용해 구간을 분리하는 로직이 핵심이다.

📊 시간/공간 복잡도 분석

ℹ️ 이 파일에는 2가지 풀이가 포함되어 있어 각각 분석합니다.

풀이 1: Solution.encode — Time: ❌ O(n) → O(total length of all strings) / Space: ❌ O(n) → O(total length of all strings)
유저 분석 실제 분석 결과
Time O(n) O(total length of all strings)
Space O(n) O(total length of all strings)

피드백: 길이 접두사 방식으로 인코딩하여 구분자를 이용해 디코딩한다.

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

풀이 2: Solution.decode — Time: O(total length of encoded string) / Space: O(number of strings + total length of strings)
복잡도
Time O(total length of encoded string)
Space O(number of strings + total length of strings)

피드백: 인덱스 기반 파싱으로 정확한 복원이 가능하다.

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

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

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

// TC: O(n)
// SC: O(n)
class Solution {

private static final String DELIMITER = ",";

// ["mydata"] -> "6,mydata"
public String encode(List<String> strs) {
StringBuilder sb = new StringBuilder();
for (String s : strs) {
sb.append(s.length()).append(DELIMITER).append(s);
}
return sb.toString();
}

// "6,mydata" -> ["mydata"]
public List<String> decode(String str) {
List<String> answer = new ArrayList<>();

int cursor = 0;
while (cursor < str.length()) {
int indexOfDelimiter = str.indexOf(DELIMITER, cursor);
int dataStart = indexOfDelimiter + 1;
int dataLength = Integer.parseInt(str.substring(cursor, indexOfDelimiter));

answer.add(str.substring(dataStart, dataStart + dataLength));
cursor = dataStart + dataLength;
}

return answer;
}
}
24 changes: 24 additions & 0 deletions group-anagrams/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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Hash Map / Hash Set, Sorting
  • 설명: 문자열의 각 문자열을 글자 정렬 후 같은 정렬 결과를 가진 문자열들을 hashmap에 모아 그룹화하는 방식으로 동작한다. 해시맵으로 키(정렬된 문자열)별로 값(원래 문자열 리스트)을 모으는 패턴이다.

📊 시간/공간 복잡도 분석

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

피드백: 정렬된 문자 배열을 해시맵 키로 사용해 애너그램 그룹화를 구현한다.

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

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

// TC: O(n * k log k)
// SC: O(n * k)
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> answer = new ArrayList<>();
Map<String, List<String>> map = new HashMap<>();

for (String str : strs) {
char[] charArray = str.toCharArray();
Arrays.sort(charArray);
String sortedStr = String.valueOf(charArray);

map.computeIfAbsent(sortedStr, k -> new ArrayList<>()).add(str);
}

for (String s : map.keySet()) {
answer.add(map.get(s));
}

return answer;
}
}
47 changes: 47 additions & 0 deletions implement-trie-prefix-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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Trie
  • 설명: 트라이(Trie) 자료구조를 활용해 단어의 접두사 매칭을 구현한 코드로, 각 문자별로 자식 노드를 따라가며 탐색/삽입을 수행합니다. 기본적으로 트라이 패턴에 해당합니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(L)
Space O(26 * number of nodes)

피드백: 배열 기반 자식 노드와 끝 여부 표시로 빠른 검색을 제공한다.

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// TC: O(L)
// SC: O(N * L)
class TrieNode {

public boolean isEnd;
public TrieNode[] children = new TrieNode[26];
}

class Trie {

private final TrieNode root;

public Trie() {
root = new TrieNode();
}

public void insert(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
if (node.children[c - 'a'] == null) {
node.children[c - 'a'] = new TrieNode();
}
node = node.children[c - 'a'];
Comment on lines +20 to +23

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.

children[c - 'a'] 는 TrieNode의 세부 구현에 가까운데 Trie에 c - 'a'가 여러 코드에 걸쳐 나타나고 있는 것 같습니다. TrieNode에서 node.getChildren(c) 와 같은 방식으로 제공하는 건 어떨까요?

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.

미처 생각 못했던 부분인데, 함수로 감싸면 가독성도 높히고 실수도 줄일 수 있을 것 같네요.
감사합니다!

}
node.isEnd = true;
}

public boolean search(String word) {
TrieNode node = traverse(word);
return node != null && node.isEnd;
}

public boolean startsWith(String prefix) {
return traverse(prefix) != null;
}

private TrieNode traverse(String sequence) {
TrieNode node = root;
for (char c : sequence.toCharArray()) {
if (node.children[c - 'a'] == null) {
return null;
}
node = node.children[c - 'a'];
}
return node;
}
}
51 changes: 51 additions & 0 deletions word-break/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, Two Pointers, Hash Map / Hash Set, Greedy
  • 설명: 주 코드에서 핵심은 DP 배열로 부분 문제를 해결하는 동적 계획법이며, 뒤에서부터 채워 전체 구문 가능 여부를 판단한다. 또한 startsWith를 이용해 부분 문자열을 검사하고 부분 문제를 재사용하므로 DP의 전형적 패턴이 드러난다. 추가적으로 주석의 top-down 재귀 역시 메모이제이션으로 DP의 다른 구현을 보여준다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(n * m * L) O(n * m)
Space O(n) O(n)

피드백: 뒤에서 앞으로 dp를 채우는 전형적 풀이로 충분하다.

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

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

// n = s.length(), m = wordDict.size(), L = 사전 단어의 최대 길이
// TC: O(n * m * L)
// SC: O(n)
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int n = s.length();

// dp[i] = 인덱스 i부터 시작하는 뒷부분을 사전 단어로 빈틈없이 쪼갤 수 있는가
boolean[] dp = new boolean[n + 1];
dp[n] = true;

// dp[i]는 자기보다 오른쪽의 dp[i + word.length()]를 참조하므로 뒤에서 앞으로 채운다
for (int i = n - 1; i >= 0; i--) {
for (String word : wordDict) {
// startsWith(word, i)는 substring 없이 i번째부터 비교한다
if (s.startsWith(word, i) && dp[i + word.length()]) {
dp[i] = true;
break;
}
}
}

return dp[0];
}
Comment on lines +15 to +26

@parkhojeong parkhojeong Jul 25, 2026

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.

재귀 형식의 탑다운 방식으로 먼저 풀다보니, 바텀업 방식도 자연스럽게 뒤에서 앞 방향으로 생각하게 되었습니다.
다른 분들께서는 어떻게 풀이하셨는지 한 번 살펴봐야겠네요.
리뷰 감사합니다!!

}

// 첫 번째 풀이 — top-down 재귀 + 메모이제이션 (TC: O(n^2 * m), SC: O(n^2))
// 남은 뒷부분을 문자열 그대로 메모 key로 써서 substring으로 새 문자열을 만들고 그 문자열을 n개까지 저장한다.
//
// public boolean wordBreak(String s, List<String> wordDict) {
// return dfs(s, wordDict, new HashMap<>());
// }
//
// private boolean dfs(String s, List<String> wordDict, Map<String, Boolean> memo) {
// if (s.isEmpty()) return true;
// if (memo.containsKey(s)) return memo.get(s);
//
// for (String word : wordDict) {
// if (s.startsWith(word)) {
// if (dfs(s.substring(word.length()), wordDict, memo)) {
// memo.put(s, true);
// return true;
// }
// }
// }
//
// memo.put(s, false);
// return false;
// }
Loading