From f1cdd1ef571a1236b6b836a7ef6b22ed83d5587f Mon Sep 17 00:00:00 2001 From: jinvicky Date: Mon, 11 Aug 2025 10:02:32 +0900 Subject: [PATCH 1/8] merge two sorted list solution --- merge-two-sorted-lists/jinvicky.java | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 merge-two-sorted-lists/jinvicky.java diff --git a/merge-two-sorted-lists/jinvicky.java b/merge-two-sorted-lists/jinvicky.java new file mode 100644 index 000000000..35ecdaabc --- /dev/null +++ b/merge-two-sorted-lists/jinvicky.java @@ -0,0 +1,32 @@ +class Solution { + public ListNode mergeTwoLists(ListNode list1, ListNode list2) { + ListNode answer = new ListNode(); + ListNode mergePointer = answer; + // 머지를 수행할 포인터와 정답을 반환할 포인터 총 2개의 포인터가 필요합니다. + // 초기화에서 정답 포인터와 머지 포인터가 같은 노드 주소를 바라보게 해야 합니다. + // 머지 포인터가 연산을 계속하더라도 정답 포인터의 next는 정렬된 첫번째 노드를 가리킬 것입니다. + // 머지 포인터는 연산을 계속하면서 참조 주소가 변경되기 때문에 그 자체로 반환하면 안됩니다. + + while (list1 != null && list2 != null) { + // list1의 값이 list2의 값보다 작거나 같으면 list1의 노드를 병합 + if (list1.val <= list2.val) { // wrong: 값이 더 작거나, 또는 값이 동일할 경우 list1을 우선시해야 합니다. + mergePointer.next = list1; + list1 = list1.next; + } else { + // 그렇지 않으면 list2의 노드를 병합 + mergePointer.next = list2; + list2 = list2.next; + } + mergePointer = mergePointer.next; + } + + // 두 리스트는 오름차순 정렬을 전제로 하기 때문에 한 리스트의 길이 끝에 도달하면 나머지는 그저 통 붙여넣기를 합니다. + // 두 리스트 중에서 null이 아닌 리스트 노드로 머지 포인터의 next에 연결합니다. + if (list1 != null) { + mergePointer.next = list1; + } else { + mergePointer.next = list2; + } + return answer.next; + } +} From 80dd434e8dc3f8b13667e0d8b688b90a216ac4cd Mon Sep 17 00:00:00 2001 From: jinvicky Date: Mon, 11 Aug 2025 10:10:24 +0900 Subject: [PATCH 2/8] max depth solution --- maximum-depth-of-binary-tree/jinvicky.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 maximum-depth-of-binary-tree/jinvicky.java diff --git a/maximum-depth-of-binary-tree/jinvicky.java b/maximum-depth-of-binary-tree/jinvicky.java new file mode 100644 index 000000000..d32ada999 --- /dev/null +++ b/maximum-depth-of-binary-tree/jinvicky.java @@ -0,0 +1,11 @@ +class Solution { + // 최대 깊이를 탐색하는 것이므로 BFS보다 DFS가 더 적절합니다. + // 매 노드의 left, right을 재귀로 호출해서 최대 깊이를 반환합니다. 재귀 함수 필요. + public int maxDepth(TreeNode root) { + // 재귀 종료 조건 == left 혹은 right가 null일 때, root 자체가 널이라면? + if (root == null) return 0; + + // 누적을 위해서 1+를 하고, Math.max()로 최댓값을 구합니다. + return 1+ Math.max(maxDepth(root.left), maxDepth(root.right)); + } +} From dba7ffd5bb04e948252570c36f51fd93e00e88aa Mon Sep 17 00:00:00 2001 From: jinvicky Date: Tue, 12 Aug 2025 11:56:16 +0900 Subject: [PATCH 3/8] word search solution --- word-search/jinvicky.java | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 word-search/jinvicky.java diff --git a/word-search/jinvicky.java b/word-search/jinvicky.java new file mode 100644 index 000000000..31f0d4e3c --- /dev/null +++ b/word-search/jinvicky.java @@ -0,0 +1,31 @@ +class Solution { + public boolean exist(char[][] board, String word) { + int m = board.length; + int n = board[0].length; + for(int i = 0; i < m; i++) { + for(int j = 0; j < n; j++) { + if(dfs(board, i, j, word, 0)) { + return true; + } + } + } + return false; + } + + boolean dfs(char[][] board,int i,int j,String word,int index){ + if(index == word.length()) return true; + if(i<0 || j<0 || i>=board.length || j>=board[0].length) return false; // 범위를 벗어난 경우 + if(board[i][j] != word.charAt(index)) return false; // 일치 조건을 불만족하는 경우 + + char temp = board[i][j]; + board[i][j] = '#'; + boolean found = dfs(board, i+1, j, word, index+1) + || dfs(board, i-1, j, word, index+1) + || dfs(board, i, j+1, word, index+1) + || dfs(board, i, j-1, word, index+1); + + board[i][j] = temp; + return found; + } + +} \ No newline at end of file From 29dbfe5947ee1a47c65028d8a41bc8da136ba71f Mon Sep 17 00:00:00 2001 From: jinvicky Date: Tue, 12 Aug 2025 11:56:36 +0900 Subject: [PATCH 4/8] fix lint --- word-search/jinvicky.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/word-search/jinvicky.java b/word-search/jinvicky.java index 31f0d4e3c..f2bb4df50 100644 --- a/word-search/jinvicky.java +++ b/word-search/jinvicky.java @@ -28,4 +28,4 @@ boolean dfs(char[][] board,int i,int j,String word,int index){ return found; } -} \ No newline at end of file +} From 4e490caeb42e7afa9f137ea70185e57a724de917 Mon Sep 17 00:00:00 2001 From: jinvicky Date: Tue, 12 Aug 2025 12:58:23 +0900 Subject: [PATCH 5/8] find minimum in rotated sorted array solution --- .../jinvicky.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 find-minimum-in-rotated-sorted-array/jinvicky.java diff --git a/find-minimum-in-rotated-sorted-array/jinvicky.java b/find-minimum-in-rotated-sorted-array/jinvicky.java new file mode 100644 index 000000000..c245a6017 --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/jinvicky.java @@ -0,0 +1,27 @@ + +class Solution { + public int findMin(int[] nums) { + int left = 0; + int right = nums.length - 1; + + // 0번째값이 length-1번재 값보다 작다면 rotate되지 않았음을 보장합니다. + // 2,3,4,5,1 0번째 > length-1번째 + // 3,4,5,1,2 0번째 > length-1번째 + // 1,2,3,4,5 0번째 < length-1번째 + if (nums[right] >= nums[left]) return nums[0]; + + while (left < right) { + // 단순히 (left+right)/2 보다 범위 계산 오차가 없습니다. + int mid = left + (right - left) / 2; + + // 중간값이 오른쪽값보다 크다면 왼쪽 포인터를 중간값+1로 증가합니다. + if (nums[mid] > nums[right]) { + left = mid + 1; + } else { + // 중간값보다 오른쪽값이 크다면 중간값이 최대 범위가 되어야 합니다. + right = mid; + } + } + return nums[left]; + } +} From 47b29ed017af26842499c6a28e1449709ab3e412 Mon Sep 17 00:00:00 2001 From: jinvicky Date: Tue, 12 Aug 2025 15:22:00 +0900 Subject: [PATCH 6/8] coin change solution --- coin-change/jinvicky.java | 16 ++++++++++++++++ .../jinvicky.java | 6 +++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 coin-change/jinvicky.java diff --git a/coin-change/jinvicky.java b/coin-change/jinvicky.java new file mode 100644 index 000000000..06ae5809b --- /dev/null +++ b/coin-change/jinvicky.java @@ -0,0 +1,16 @@ +import java.util.Arrays; + +class Solution { + public int coinChange(int[] coins, int amount) { + int max=amount+1; + int [] dp=new int[amount+1]; + Arrays.fill(dp,max); + dp[0]=0; + for(int coin:coins){ + for(int j=coin;j<=amount;j++){ // coin부터 시작해서 일반 루프보다 성능 향상 + dp[j]=Math.min(dp[j],dp[j-coin]+1); + } + } + return dp[amount]>amount ? -1:dp[amount]; + } +} \ No newline at end of file diff --git a/find-minimum-in-rotated-sorted-array/jinvicky.java b/find-minimum-in-rotated-sorted-array/jinvicky.java index c245a6017..e762353ad 100644 --- a/find-minimum-in-rotated-sorted-array/jinvicky.java +++ b/find-minimum-in-rotated-sorted-array/jinvicky.java @@ -15,13 +15,17 @@ public int findMin(int[] nums) { int mid = left + (right - left) / 2; // 중간값이 오른쪽값보다 크다면 왼쪽 포인터를 중간값+1로 증가합니다. - if (nums[mid] > nums[right]) { + if (nums[mid] > nums[right]) { // <= 와 동일 left = mid + 1; } else { // 중간값보다 오른쪽값이 크다면 중간값이 최대 범위가 되어야 합니다. + // 최소값이 mid일 가능성이 있기 때문이다. right = mid; } } return nums[left]; } } + +// 처음에는 전형 이진 탐색으로서 left = mid+1, right = mid-1을 했으나 실패 +// 하지만 최소 숫자는 무조건 left가 가리키는 값임. From 6b7469b001928b81db290a8667f93cc7ee0a190b Mon Sep 17 00:00:00 2001 From: jinvicky Date: Tue, 12 Aug 2025 15:22:21 +0900 Subject: [PATCH 7/8] fix lint --- coin-change/jinvicky.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coin-change/jinvicky.java b/coin-change/jinvicky.java index 06ae5809b..c7e0ce392 100644 --- a/coin-change/jinvicky.java +++ b/coin-change/jinvicky.java @@ -13,4 +13,4 @@ public int coinChange(int[] coins, int amount) { } return dp[amount]>amount ? -1:dp[amount]; } -} \ No newline at end of file +} From 2b1cf5a609bdee5b8654b760b66cbbd014b7d11a Mon Sep 17 00:00:00 2001 From: jinvicky Date: Thu, 14 Aug 2025 12:51:03 +0900 Subject: [PATCH 8/8] add comment --- maximum-depth-of-binary-tree/jinvicky.java | 11 +++++ word-search/jinvicky.java | 51 ++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/maximum-depth-of-binary-tree/jinvicky.java b/maximum-depth-of-binary-tree/jinvicky.java index d32ada999..0f3dd66fe 100644 --- a/maximum-depth-of-binary-tree/jinvicky.java +++ b/maximum-depth-of-binary-tree/jinvicky.java @@ -1,3 +1,14 @@ +// 왼쪽 서브트리를 모두 탐색한 다음 오른쪽 서브트리 탐색을 시작 +// 1 (root) +// / \ +// 2 3 +// / \ / \ +// 4 5 6 7 +// +// root를 인자로 받아서 노드별로 left, right을 또 재귀로 호출하니 +// (1)의 left, right, (2)의 left, right, (3)의 left, right, (4)의 left, right이 실행된다. +// 결과적으로 왼쪽 서브트리의 최대 depth와 오른쪽 서브트리의 최대 depth + 최초 root의 depth 1을 합해서 완성 +// Math.max()는 함수 안의 모든 값이 계산되어야만 실행된다. class Solution { // 최대 깊이를 탐색하는 것이므로 BFS보다 DFS가 더 적절합니다. // 매 노드의 left, right을 재귀로 호출해서 최대 깊이를 반환합니다. 재귀 함수 필요. diff --git a/word-search/jinvicky.java b/word-search/jinvicky.java index f2bb4df50..e61731c16 100644 --- a/word-search/jinvicky.java +++ b/word-search/jinvicky.java @@ -28,4 +28,55 @@ boolean dfs(char[][] board,int i,int j,String word,int index){ return found; } + // 2차원 방문 배열을 만들고 direction 방향 템플릿으로 풀이 + public boolean exist2(char[][] board, String word) { + int m = board.length; + int n = board[0].length; + boolean[][] visited = new boolean[m][n]; + boolean result = false; + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (board[i][j] == word.charAt(0)) { + result = backtrack(board, word, visited, i, j, 0); + if (result) + return true; + } + } + } + + return false; + } + + private boolean backtrack(char[][] board, String word, boolean[][] visited, int i, int j, int index) { + if (index == word.length()) { + return true; + } + + // dfs를 풀 때는 배열 범위를 벗어나는 경우 break를 꼭 기억하기 + if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || visited[i][j] + || board[i][j] != word.charAt(index)) { + return false; + } + + visited[i][j] = true; + + // if문에서 작성하는 것이 눈에 안 익어서 + // direction 템플릿을 만들어서 for문으로 해결하는 암기법으로 변환 + int[][] directions = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }; // 그냥 암기 + + for (int[] dir : directions) { + // i가 y, j가 x인데 사실 1, -1, 0만 잘 설정하면 상관없음. 목적은 1, -1 1번씩 그리고 나머지는 0으로 채우는 것 + int nextI = i + dir[0]; + int nextJ = j + dir[1]; + + if (backtrack(board, word, visited, nextI, nextJ, index + 1)) { + return true; + } + } + + visited[i][j] = false; + return false; + } + }