diff --git a/coin-change/Tessa1217.java b/coin-change/Tessa1217.java new file mode 100644 index 000000000..b47bef872 --- /dev/null +++ b/coin-change/Tessa1217.java @@ -0,0 +1,26 @@ +/** + * 정수 배열 coins가 주어졌을 때 amount를 만들 기 위해 최소한의 동전 개수를 반환하세요. + 만약 동적으로 amount 조합을 만들어낼 수 없다면 -1을 리턴하세요. + */ +import java.util.Arrays; + +class Solution { + + // 시간복잡도: O(n * amount), 공간복잡도: O(amount) + public int coinChange(int[] coins, int amount) { + int[] coinCnt = new int[amount + 1]; + // coins[i]의 최댓값이 2^31 - 1 이므로 최댓값 설정 + Arrays.fill(coinCnt, Integer.MAX_VALUE - 1); + coinCnt[0] = 0; + for (int i = 0; i < coins.length; i++) { + for (int j = coins[i]; j < amount + 1; j++) { + coinCnt[j] = Math.min(coinCnt[j], coinCnt[j - coins[i]] + 1); + } + } + if (coinCnt[amount] == Integer.MAX_VALUE - 1) { + return -1; + } + return coinCnt[amount]; + } +} + diff --git a/find-minimum-in-rotated-sorted-array/Tessa1217.java b/find-minimum-in-rotated-sorted-array/Tessa1217.java new file mode 100644 index 000000000..71ea3617f --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/Tessa1217.java @@ -0,0 +1,38 @@ +/** + * 길이가 n인 오름차순으로 정렬된 숫자 배열이 1 ~ n번 회전했다. 회전된 배열에서 가장 작은 수를 찾아서 반환하시오. + */ +class Solution { + + // 이진 탐색: 시간복잡도: O(log n) + public int findMin(int[] nums) { + int left = 0; + int right = nums.length - 1; + while (left < right) { + int mid = (left + right) / 2; + if (nums[mid] > nums[right]) { + left = mid + 1; + } else { + right = mid; + } + } + return nums[left]; + } + + +// 1차는 단순하게 앞뒤 배열 요소 비교로 풀어봄: O(n^2) +// Submission은 되었지만 시간 복잡도 기준을 못 맞춘 것 같아서 이진 탐색으로 재풀이 진행 +// public int findMin(int[] nums) { +// int rotate = 0; +// for (int i = 0; i < nums.length - 1; i++) { +// int idx = (i + rotate) < nums.length ? (i + rotate) : (i + rotate) - nums.length; +// int nextIdx = idx + 1 < nums.length ? idx + 1 : nums.length - (idx + 1); +// if (nums[idx] > nums[nextIdx]) { +// rotate++; +// i = -1; +// } +// } +// return nums[rotate]; +// } + +} + diff --git a/maximum-depth-of-binary-tree/Tessa1217.java b/maximum-depth-of-binary-tree/Tessa1217.java new file mode 100644 index 000000000..8afdadb80 --- /dev/null +++ b/maximum-depth-of-binary-tree/Tessa1217.java @@ -0,0 +1,41 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +/** + * 이진 트리의 루트가 주어질 때 최대 깊이를 구하세요. + */ +class Solution { + + int maxDepth = 0; + + // 시간 복잡도: O(n) + public int maxDepth(TreeNode root) { + depthChk(root, 0); + return maxDepth; + } + + // 재귀로 풀이 진행 + public void depthChk(TreeNode node, int depth) { + // 탐색할 노드 없을 경우 + if (node == null) { + maxDepth = Math.max(depth, maxDepth); + return; + } + // 트리의 좌우 탐색 + depthChk(node.left, depth + 1); + depthChk(node.right, depth + 1); + } +} + diff --git a/merge-two-sorted-lists/Tessa1217.java b/merge-two-sorted-lists/Tessa1217.java new file mode 100644 index 000000000..d6af9341a --- /dev/null +++ b/merge-two-sorted-lists/Tessa1217.java @@ -0,0 +1,30 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +/** + 정렬된 링크드 리스트 list1과 list2가 주어질 때 두 리스트를 하나의 정렬된 리스트로 반환하도록 구현하세요. + */ +class Solution { + + // 시간 복잡도: O(l1 + l2), l1과 l2는 리스트 각각의 길이 + public ListNode mergeTwoLists(ListNode list1, ListNode list2) { + if (list1 == null || list2 == null) { + return list1 == null ? list2 : list1; + } + if (list1.val < list2.val) { + list1.next = mergeTwoLists(list1.next, list2); + return list1; + } else { + list2.next = mergeTwoLists(list2.next, list1); + return list2; + } + } +} + diff --git a/word-search/Tessa1217.java b/word-search/Tessa1217.java new file mode 100644 index 000000000..40f1ac55e --- /dev/null +++ b/word-search/Tessa1217.java @@ -0,0 +1,67 @@ +/** + * character들로 이루어진 m*n 행렬 board와 word 문자열이 주어질 때 해당 문자열이 행렬 내에 존재할 수 있는지 + * 여부를 불린형으로 반환하세요. (상하좌우로 연결, 셀은 한번만 사용 가능) + */ +class Solution { + + int[] dx = {-1, 1, 0, 0}; + + int[] dy = {0, 0, -1, 1}; + + int rows, cols; + + // 시간 복잡도: O(M * N * 4^L) + public boolean exist(char[][] board, String word) { + rows = board.length; + cols = board[0].length; + + // 셀 사용 여부를 나타내는 방문 배열 + boolean[][] visited = new boolean[rows][cols]; + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + // 글자의 시작점부터 DFS + if (board[i][j] == word.charAt(0)) { + if (dfs(i, j, 0, visited, board, word)) { + return true; + } + } + } + } + return false; + } + + // x, y가 board 벗어나지 않는지 + private boolean isRange(int x, int y) { + return x >= 0 && x < rows && y >= 0 && y < cols; + } + + // DFS + private boolean dfs(int x, int y, int idx, boolean[][] visited, char[][] board, String word) { + + if (idx == word.length()) { + return true; + } + + if (!isRange(x, y) || visited[x][y] || board[x][y] != word.charAt(idx)) { + return false; + } + + visited[x][y] = true; + + // 상하좌우 + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + if (dfs(nx, ny, idx + 1, visited, board, word)) { + return true; + } + } + + visited[x][y] = false; + + return false; + + } +} +