Skip to content

[Ackku] week 14 #1105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 16, 2025
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
38 changes: 20 additions & 18 deletions binary-tree-level-order-traversal/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
// dfs와 분할 정복법으로 해결되는 문제
// dfs인 것을 알았으나 모든 숫자가 음수일 경우를 판별하지 못해 GPT에게 도움을 처함
// 그동안의 대부분의 트리문제는 DFS로 해결 됐어서.. 그렇게 해야하 싶었는데
// 가로로 나열되기 때문에 BFS가 적합함
// 한번의 순회로 해결되기 때문에 시간 복잡도는 O(N)
class Solution {
private int maxSum = Integer.MIN_VALUE; // 전체 최대 경로 합 저장
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;

public int maxPathSum(TreeNode root) {
dfs(root);
return maxSum;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

private int dfs(TreeNode node) {
if (node == null) return 0; // base case
while (!queue.isEmpty()) {
int levelSize = queue.size();
List<Integer> level = new ArrayList<>();

// 왼쪽, 오른쪽 서브트리의 최대 경로 합 (음수는 포함 X → Math.max(0, value))
int left = Math.max(0, dfs(node.left));
int right = Math.max(0, dfs(node.right));
for (int i = 0; i < levelSize; i++) {
TreeNode node = queue.poll();
level.add(node.val);

// 현재 노드를 포함한 최대 경로 (왼쪽 + 루트 + 오른쪽)
int pathSum = left + node.val + right;
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}

// 최대 경로 값 갱신
maxSum = Math.max(maxSum, pathSum);
result.add(level);
}

// ✅ 현재 노드를 포함하는 최대 경로 값만 반환해야 함 (연결 가능한 경로)
return node.val + Math.max(left, right);
return result;
}
}
27 changes: 27 additions & 0 deletions binary-tree-maximum-path-sum/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// dfs와 분할 정복법으로 해결되는 문제
// dfs인 것을 알았으나 모든 숫자가 음수일 경우를 판별하지 못해 GPT에게 도움을 처함
class Solution {
private int maxSum = Integer.MIN_VALUE; // 전체 최대 경로 합 저장

public int maxPathSum(TreeNode root) {
dfs(root);
return maxSum;
}

private int dfs(TreeNode node) {
if (node == null) return 0; // base case

// 왼쪽, 오른쪽 서브트리의 최대 경로 합 (음수는 포함 X → Math.max(0, value))
int left = Math.max(0, dfs(node.left));
int right = Math.max(0, dfs(node.right));

// 현재 노드를 포함한 최대 경로 (왼쪽 + 루트 + 오른쪽)
int pathSum = left + node.val + right;

// 최대 경로 값 갱신
maxSum = Math.max(maxSum, pathSum);

// ✅ 현재 노드를 포함하는 최대 경로 값만 반환해야 함 (연결 가능한 경로)
return node.val + Math.max(left, right);
}
}
10 changes: 10 additions & 0 deletions counting-bits/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Integer.bitCount(i)는 O(log n) 이걸림 그래서 n번 반복하면 O(nlogn)
public static int[] countBits(int n) {
int[] ans = new int[n + 1];

for (int i = 0; i <= n; i++) {
ans[i] = Integer.bitCount(i);
}

return ans;
}
31 changes: 31 additions & 0 deletions house-robber-ii/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// house robber 1이 dp문제여서 dp문제라는거 알 수 있었음
// 시작점을 다르게 해서 두개의 dp를 결합하는 아이디어는 맞았음(첫 집을 털었을때, 마지막 집을 털었을 때)
// 구현이 너무 오래걸려서 GPT의 도움을 받음..
// DP는 아이디어가 절반이라 생각했는데 구현을 잘 못해서 아쉬움
Comment on lines +3 to +4
Copy link
Contributor

Choose a reason for hiding this comment

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

전 아직 아이디어 구현도 어려운데, 절반은 성공하셨네요 👍
남은 2주간 화이팅입니다..!

class Solution {
public int rob(int[] nums) {
if (nums.length == 1) return nums[0]; // 집이 하나면 그 집만 털면 됨.

int n = nums.length;

// 1. 첫 번째 집을 포함하지 않는 경우 (nums[1] ~ nums[n-1])
int[] dp1 = new int[n];
dp1[0] = 0; // 첫 번째 집을 포함하지 않으므로 0
dp1[1] = nums[1]; // 두 번째 집을 털었을 경우

for (int i = 2; i < n; i++) {
dp1[i] = Math.max(dp1[i - 1], dp1[i - 2] + nums[i]);
}

// 2. 마지막 집을 포함하지 않는 경우 (nums[0] ~ nums[n-2])
int[] dp2 = new int[n];
dp2[0] = nums[0]; // 첫 번째 집을 털었을 경우
dp2[1] = Math.max(nums[0], nums[1]); // 두 번째 집을 털지 않을 수도 있음

for (int i = 2; i < n - 1; i++) {
dp2[i] = Math.max(dp2[i - 1], dp2[i - 2] + nums[i]);
}

return Math.max(dp1[n - 1], dp2[n - 2]);
}
}
30 changes: 30 additions & 0 deletions meeting-rooms-ii/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 정렬을 이용하면 O(nlogn)으로 풀리는데 다른 아이디어가 안떠오름
class Solution {
public int minMeetingRooms(int[][] intervals) {
if (intervals == null || intervals.length == 0) return 0;

int n = intervals.length;
int[] startTimes = new int[n];
int[] endTimes = new int[n];

for (int i = 0; i < n; i++) {
startTimes[i] = intervals[i][0];
endTimes[i] = intervals[i][1];
}

Arrays.sort(startTimes);
Arrays.sort(endTimes);

int rooms = 0;
int endPointer = 0;

for (int startPointer = 0; startPointer < n; startPointer++) {
if (startTimes[startPointer] < endTimes[endPointer]) {
rooms++;
endPointer++;
}
}

return rooms;
}
}
68 changes: 68 additions & 0 deletions word-search-ii/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// 모든 위치에서 DFS를 실행 or BFS를 돌면서 단어 찾는 경우 모든 경우에 타임아웃이 발생
// 도저히 해결을 못할거 같아서 GPT의 도움을 받음
// Trie를 이용했는데 조금 더 고민해봐야할 듯
class TrieNode {
Map<Character, TrieNode> children = new HashMap<>();
String word = null;
}

class Solution {
public List<String> findWords(char[][] board, String[] words) {
List<String> result = new ArrayList<>();
TrieNode root = buildTrie(words);

for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
dfs(board, i, j, root, result);
}
}
return result;
}

// Trie(트라이) 자료구조를 구축
private TrieNode buildTrie(String[] words) {
TrieNode root = new TrieNode();
for (String word : words) {
TrieNode node = root;
for (char c : word.toCharArray()) {
node.children.putIfAbsent(c, new TrieNode());
node = node.children.get(c);
}
node.word = word;
}
return root;
}

// DFS + 백트래킹 탐색
private void dfs(char[][] board, int i, int j, TrieNode node, List<String> result) {
char c = board[i][j];
if (!node.children.containsKey(c)) return; // 현재 문자와 일치하는 것이 Trie에 없으면 종료

TrieNode nextNode = node.children.get(c);
if (nextNode.word != null) { // 단어를 찾았으면 결과 리스트에 추가
result.add(nextNode.word);
nextNode.word = null; // 중복 방지를 위해 제거
}

// 방문 표시 (백트래킹을 위해)
board[i][j] = '#';

// 4방향 탐색
int[] dx = {-1, 1, 0, 0};
int[] dy = {0, 0, -1, 1};
for (int d = 0; d < 4; d++) {
int x = i + dx[d], y = j + dy[d];
if (x >= 0 && x < board.length && y >= 0 && y < board[0].length) {
dfs(board, x, y, nextNode, result);
}
}

// 백트래킹 (원래 문자로 복원)
board[i][j] = c;

// **최적화**: 더 이상 자식이 없으면 Trie에서 해당 노드 삭제
if (nextNode.children.isEmpty()) {
node.children.remove(c);
}
}
}