diff --git a/binary-tree-level-order-traversal/forest000014.java b/binary-tree-level-order-traversal/forest000014.java new file mode 100644 index 000000000..57840a2d0 --- /dev/null +++ b/binary-tree-level-order-traversal/forest000014.java @@ -0,0 +1,42 @@ +/* +# Time Complexity: O(n) +# Space Complexity: O(n) + - 재귀 호출 함수의 파라미터 root, depth, ans +*/ + +/** + * 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 { + public List> levelOrder(TreeNode root) { + List> ans = new ArrayList<>(); + + dfs(root, 0, ans); + + return ans; + } + + private void dfs(TreeNode root, int depth, List> ans) { + if (root == null) return; + + if (ans.size() == depth) { + ans.add(new ArrayList<>()); + } + ans.get(depth).add(root.val); + + dfs(root.left, depth + 1, ans); + dfs(root.right, depth + 1, ans); + } +} diff --git a/counting-bits/forest000014.java b/counting-bits/forest000014.java new file mode 100644 index 000000000..0bba6aac0 --- /dev/null +++ b/counting-bits/forest000014.java @@ -0,0 +1,19 @@ +/* +# Time Complexity: O(n) +# Space Complexity: O(1) +*/ +class Solution { + public int[] countBits(int n) { + int[] ans = new int[n + 1]; + + for (int i = 0; i <= n; i++) { + int x = i; + while (x > 0) { + ans[i] += (x & 1); + x >>= 1; + } + } + + return ans; + } +} diff --git a/house-robber-ii/forest000014.java b/house-robber-ii/forest000014.java new file mode 100644 index 000000000..67d05198d --- /dev/null +++ b/house-robber-ii/forest000014.java @@ -0,0 +1,30 @@ +/* +# Time Complexity: O(n) +# Space Complexity: O(n) +*/ +class Solution { + public int rob(int[] nums) { + int n = nums.length; + if (n == 1) return nums[0]; + + int[][][] dp = new int[n][2][2]; + + dp[0][0][0] = 0; + dp[0][0][1] = 0; + dp[0][1][0] = 0; // + dp[0][1][1] = nums[0]; + for (int i = 1; i < n - 1; i++) { + dp[i][0][0] = Math.max(dp[i - 1][0][0], dp[i - 1][1][0]); + dp[i][0][1] = Math.max(dp[i - 1][0][1], dp[i - 1][1][1]); + dp[i][1][0] = dp[i - 1][0][0] + nums[i]; + dp[i][1][1] = dp[i - 1][0][1] + nums[i]; + } + + dp[n - 1][0][0] = Math.max(dp[n - 2][0][0], dp[n - 2][1][0]); + dp[n - 1][0][1] = Math.max(dp[n - 2][0][1], dp[n - 2][1][1]); + dp[n - 1][1][0] = dp[n - 2][0][0] + nums[n - 1]; + dp[n - 1][1][1] = -1; + + return Math.max(Math.max(dp[n - 1][0][0], dp[n - 1][0][1]), dp[n - 1][1][0]); + } +} diff --git a/meeting-rooms-ii/forest000014.java b/meeting-rooms-ii/forest000014.java new file mode 100644 index 000000000..9b183ce48 --- /dev/null +++ b/meeting-rooms-ii/forest000014.java @@ -0,0 +1,42 @@ +/* +# Time Complexity: O(nlogn) +# Space Complexity: O(n) +*/ + +class Solution { + + private class Info { + int kind; // start = 0, end = 1 + int time; + + Info(int kind, int time) { + this.kind = kind; + this.time = time; + } + } + public int minMeetingRooms(int[][] intervals) { + int n = intervals.length; + List infos = new ArrayList<>(); + for (int i = 0; i < n; i++) { + infos.add(new Info(0, intervals[i][0])); + infos.add(new Info(1, intervals[i][1])); + } + + Collections.sort(infos, (o1, o2) -> { + if (o1.time == o2.time) { + return Integer.compare(o2.kind, o1.kind); + } + return Integer.compare(o1.time, o2.time); + }); + + int cnt = 0; + int ans = 0; + for (Info info : infos) { + if (info.kind == 0) cnt++; + else cnt--; + ans = Math.max(ans, cnt); + } + + return ans; + } +} diff --git a/subtree-of-another-tree/forest000014.java b/subtree-of-another-tree/forest000014.java new file mode 100644 index 000000000..b28836799 --- /dev/null +++ b/subtree-of-another-tree/forest000014.java @@ -0,0 +1,48 @@ +/* +# Time Complexity: O(n) +# Space Complexity: O(n) + - 재귀 호출 파라미터 O(n) 사이즈 공간 필요 +*/ + +/** + * 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 { + public boolean isSubtree(TreeNode root, TreeNode subRoot) { + return dfs(root, subRoot); + } + + private boolean dfs(TreeNode root, TreeNode subRoot) { + if (root == null && subRoot == null) return true; + if (root == null || subRoot == null) return false; + + if (root.val == subRoot.val) { + if (compareTrees(root, subRoot)) return true; + } + + if (dfs(root.left, subRoot)) return true; + if (dfs(root.right, subRoot)) return true; + + return false; + } + + private boolean compareTrees(TreeNode root1, TreeNode root2) { + if (root1 == null && root2 == null) return true; + if (root1 == null || root2 == null) return false; + if (root1.val != root2.val) return false; + + return compareTrees(root1.left, root2.left) && compareTrees(root1.right, root2.right); + } +} diff --git a/word-search-ii/forest000014.java b/word-search-ii/forest000014.java new file mode 100644 index 000000000..39c6ed9f1 --- /dev/null +++ b/word-search-ii/forest000014.java @@ -0,0 +1,73 @@ +/* +# Time Complexity: O(w + m * n * 4^10) + - trie에 word 하나(최대 길이 10)를 삽입하는 데에는 O(10) = O(1) 이므로, trie 전체를 생성하는 데에는 O(w) (w는 words의 length) + - dfs 탐색을 하면서, 모든 경로를 탐색 (최대 depth는 10) +# Space Complexity: O(w) + - trie를 생성하면, 최대 10글자 * w개 문자열 = O(10w) = O(w) +*/ +class Solution { + + private class Trie { + char val; + boolean ends; + Map children; + + Trie(char val) { + this.val = val; + this.children = new HashMap<>(); + } + } + public List findWords(char[][] board, String[] words) { + // Trie 생성 및 세팅 + Trie root = new Trie('.'); + for (String word : words) { + Trie curr = root; + for (int i = 0; i < word.length(); i++) { + char ch = word.charAt(i); + curr.children.putIfAbsent(ch, new Trie(ch)); + curr = curr.children.get(ch); + } + curr.ends = true; + } + + // trie와 dfs를 사용하여, 단어가 존재하는지 확인 + int m = board.length; + int n = board[0].length; + boolean[][] visited = new boolean[m][n]; + StringBuilder sb = new StringBuilder(); + Set ans = new HashSet<>(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (!root.children.containsKey(board[i][j])) continue; + + visited[i][j] = true; + sb.append(board[i][j]); + dfs(m, n, board, visited, i, j, root.children.get(board[i][j]), sb, ans); // + sb.deleteCharAt(0); + visited[i][j] = false; + } + } + + return ans.stream().collect(Collectors.toList()); + } + + private void dfs(int m, int n, char[][] board, boolean[][] visited, int r, int c, Trie curr, StringBuilder sb, Set ans) { + if (curr.ends) ans.add(sb.toString()); + + int[] dr = {-1, 0, 1, 0}; + int[] dc = {0, 1, 0, -1}; + + for (int i = 0; i < 4; i++) { + int nr = r + dr[i]; + int nc = c + dc[i]; + if (nr < 0 || nr >= m || nc < 0 || nc >= n || visited[nr][nc]) continue; + if (!curr.children.containsKey(board[nr][nc])) continue; + + visited[nr][nc] = true; + sb.append(board[nr][nc]); + dfs(m, n, board, visited, nr, nc, curr.children.get(board[nr][nc]), sb, ans); + sb.deleteCharAt(sb.length() - 1); + visited[nr][nc] = false; + } + } +}