diff --git a/binary-tree-level-order-traversal/minji-go.java b/binary-tree-level-order-traversal/minji-go.java new file mode 100644 index 000000000..fe06e1149 --- /dev/null +++ b/binary-tree-level-order-traversal/minji-go.java @@ -0,0 +1,34 @@ +/** + * week14-2. binary-tree-level-order-traversal + *
  • Description: Given the root of a binary tree, return the level order traversal of its nodes' values. (i.e., from left to right, level by level)
  • + *
  • Topics: Tree, Breadth-First Search, Binary Tree
  • + *
  • Time Complexity: O(N), Runtime 1ms
  • + *
  • Space Complexity: O(N), Memory 45.3MB
  • + */ + +class Solution { + public List> levelOrder(TreeNode root) { + if (root == null) { + return Collections.emptyList(); + } + + Queue queue = new LinkedList<>(); + queue.offer(root); + + List> results = new ArrayList<>(); + while (!queue.isEmpty()) { + List result = new ArrayList<>(); + + int size = queue.size(); + for (int i = 0; i < size; i++) { + TreeNode node = queue.poll(); + result.add(node.val); + if (node.left != null) queue.offer(node.left); + if (node.right != null) queue.offer(node.right); + } + results.add(result); + } + + return results; + } +} diff --git a/counting-bits/minji-go.java b/counting-bits/minji-go.java new file mode 100644 index 000000000..d9b284a04 --- /dev/null +++ b/counting-bits/minji-go.java @@ -0,0 +1,20 @@ +/** + * week14-1. counting-bits + *
  • Description: Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n), ans[i] is the number of 1's in the binary representation of i
  • + *
  • Topics: Dynamic Programming, Bit Manipulation
  • + *
  • Time Complexity: O(N), Runtime 2ms
  • + *
  • Space Complexity: O(N), Memory 46.64MB
  • + */ +class Solution { + public int[] countBits(int n) { + int[] count = new int[n + 1]; + + int offset = 1; + for (int i = 1; i <= n; i++) { + if (i == offset * 2) offset *= 2; + count[i] = count[i - offset] + 1; + } + + return count; + } +} diff --git a/house-robber-ii/minji-go.java b/house-robber-ii/minji-go.java new file mode 100644 index 000000000..4bf006a67 --- /dev/null +++ b/house-robber-ii/minji-go.java @@ -0,0 +1,27 @@ +/** + * week14-3. house-robber-ii + *
  • Description: Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police
  • + *
  • Topics: Array, Dynamic Programming
  • + *
  • Time Complexity: O(N), Runtime 0ms
  • + *
  • Space Complexity: O(1), Memory 40.6MB
  • + */ + +class Solution { + public int rob(int[] nums) { + int n = nums.length; + if (n == 1) return nums[0]; + if (n == 2) return Math.max(nums[0], nums[1]); + + return Math.max(rob(nums, 0, n - 2), rob(nums, 1, n - 1)); + } + + public int rob(int[] nums, int start, int end) { + int prev1 = 0, prev2 = 0; + for (int i = start; i <= end; i++) { + int temp = Math.max(prev2, prev1 + nums[i]); + prev1 = prev2; + prev2 = temp; + } + return prev2; + } +} diff --git a/linked-list-cycle/minji-go.java b/linked-list-cycle/minji-go.java new file mode 100644 index 000000000..0414c2402 --- /dev/null +++ b/linked-list-cycle/minji-go.java @@ -0,0 +1,27 @@ +/** + * week9-1. linked-list-cycle + *
  • Description: Return true if there is a cycle in the linked list.
  • + *
  • Topics: Hash Table, Linked List, Two Pointers
  • + *
  • Time Complexity: O(N), Runtime 0ms
  • + *
  • Space Complexity: O(1), Memory 44.37MB
  • + */ +public class Solution { + public boolean hasCycle(ListNode head) { + if (head == null) { + return false; + } + + ListNode slow = head; + ListNode fast = head.next; + + while (slow != fast) { + if (fast == null || fast.next == null) { + return false; + } + slow = slow.next; + fast = fast.next.next; + } + + return true; + } +} diff --git a/maximum-product-subarray/minji-go.java b/maximum-product-subarray/minji-go.java new file mode 100644 index 000000000..39c516b5d --- /dev/null +++ b/maximum-product-subarray/minji-go.java @@ -0,0 +1,26 @@ +/** + * week9-3. maximum-product-subarray + *
  • Description: Given an integer array nums, find a subarray that has the largest product, and return the product.
  • + *
  • Topics: Array, Dynamic Programming
  • + *
  • Time Complexity: O(N), Runtime 2ms
  • + *
  • Space Complexity: O(1), Memory 45.42MB
  • + */ +class Solution { + public int maxProduct(int[] nums) { + int maxSoFar = nums[0]; + int minSoFar = nums[0]; + int result = nums[0]; + + for (int i = 1; i < nums.length; i++) { + int cur = nums[i]; + int tempMax = maxSoFar; + + maxSoFar = Math.max(cur, Math.max(cur * maxSoFar, cur * minSoFar)); + minSoFar = Math.min(cur, Math.min(cur * tempMax, cur * minSoFar)); + + result = Math.max(result, maxSoFar); + } + + return result; + } +} diff --git a/minimum-window-substring/minji-go.java b/minimum-window-substring/minji-go.java new file mode 100644 index 000000000..dbd6db3b1 --- /dev/null +++ b/minimum-window-substring/minji-go.java @@ -0,0 +1,50 @@ +/** + * week9-5. minimum-window-substring + *
  • Description: return the minimum window substring of s such that every character in t (including duplicates) is included in the window
  • + *
  • Topics: Hash Table, String, Sliding Window
  • + *
  • Time Complexity: O(M+N), Runtime 23ms
  • + *
  • Space Complexity: O(1), Memory 45.13MB
  • + */ +class Solution { + public String minWindow(String s, String t) { + if (s.length() < t.length()) return ""; + + Map tmap = new HashMap<>(); + for (char c : t.toCharArray()) { + tmap.put(c, tmap.getOrDefault(c, 0) + 1); + } + + Map smap = new HashMap<>(); + int left = 0, right = 0; + int tsize = tmap.size(); + int ssize = 0; + int start = -1, end = s.length(); + + while (right < s.length()) { + char c = s.charAt(right++); + if (tmap.containsKey(c)) { + smap.put(c, smap.getOrDefault(c, 0) + 1); + if (smap.get(c).intValue() == tmap.get(c).intValue()) { + ssize++; + } + } + + while (ssize == tsize) { + if (right - left < end - start) { + start = left; + end = right; + } + + char l = s.charAt(left++); + if (tmap.containsKey(l)) { + smap.put(l, smap.get(l) - 1); + if (smap.get(l).intValue() < tmap.get(l).intValue()) { + ssize--; + } + } + } + } + + return start == -1 ? "" : s.substring(start, end); + } +} diff --git a/pacific-atlantic-water-flow/minji-go.java b/pacific-atlantic-water-flow/minji-go.java new file mode 100644 index 000000000..d9d64e8f7 --- /dev/null +++ b/pacific-atlantic-water-flow/minji-go.java @@ -0,0 +1,71 @@ +/** + * week9-2. pacific-atlantic-water-flow + *
  • Description: Return a 2D list of grid coordinates result where result[i] = [ri, ci] denotes that rain water can flow from cell (ri, ci) to both the Pacific and Atlantic oceans.
  • + *
  • Topics: Array, Depth-First Search, Breadth-First Search, Matrix
  • + *
  • Time Complexity: O(MN), Runtime 9ms
  • + *
  • Space Complexity: O(MN), Memory 45.18MB
  • + */ +class Solution { + private int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; + + public List> pacificAtlantic(int[][] heights) { + int m = heights.length; + int n = heights[0].length; + + Queue pacificQueue = new LinkedList<>(); + boolean[][] pacific = new boolean[m][n]; + for (int i = 0; i < m; i++) { + pacific[i][0] = true; + pacificQueue.offer(new int[]{i, 0}); + } + for (int i = 0; i < n; i++) { + pacific[0][i] = true; + pacificQueue.offer(new int[]{0, i}); + } + bfs(heights, pacificQueue, pacific); + + Queue atlanticQueue = new LinkedList<>(); + boolean[][] atlantic = new boolean[m][n]; + for (int i = 0; i < m; i++) { + atlantic[i][n - 1] = true; + atlanticQueue.offer(new int[]{i, n - 1}); + } + for (int i = 0; i < n; i++) { + atlantic[m - 1][i] = true; + atlanticQueue.offer(new int[]{m - 1, i}); + } + bfs(heights, atlanticQueue, atlantic); + + List> result = new ArrayList<>(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (pacific[i][j] && atlantic[i][j]) { + result.add(List.of(i, j)); + } + } + } + return result; + } + + + private void bfs(int[][] heights, Queue queue, boolean[][] visit) { + while (!queue.isEmpty()) { + int[] curr = queue.poll(); + int cr = curr[0]; + int cc = curr[1]; + + for (int[] dir : directions) { + int nr = cr + dir[0]; + int nc = cc + dir[1]; + + if (nr < 0 || nr > heights.length - 1 || nc < 0 || nc > heights[0].length - 1 || visit[nr][nc]) { + continue; + } + if (heights[nr][nc] >= heights[cr][cc]) { + visit[nr][nc] = true; + queue.offer(new int[]{nr, nc}); + } + } + } + } +} diff --git a/sum-of-two-integers/minji-go.java b/sum-of-two-integers/minji-go.java new file mode 100644 index 000000000..2630ada5f --- /dev/null +++ b/sum-of-two-integers/minji-go.java @@ -0,0 +1,17 @@ +/** + * week9-4. sum-of-two-integers + *
  • Description: Given two integers a and b, return the sum of the two integers without using the operators + and -.
  • + *
  • Topics: Math, Bit Manipulation
  • + *
  • Time Complexity: O(1), Runtime 0ms
  • + *
  • Space Complexity: O(1), Memory 40.51MB
  • + */ +class Solution { + public int getSum(int a, int b) { + while (b != 0) { + int tmp = (a & b) << 1; + a = (a ^ b); + b = tmp; + } + return a; + } +} diff --git a/word-search-ii/minji-go.java b/word-search-ii/minji-go.java new file mode 100644 index 000000000..a1cb1ba9e --- /dev/null +++ b/word-search-ii/minji-go.java @@ -0,0 +1,73 @@ +/** + * week14-5. word-search-ii + *
  • Description: Given an m x n board of characters and a list of strings words, return all words on the board.
  • + *
  • Topics: Array, String, Backtracking, Trie, Matrix
  • + *
  • Time Complexity: O(M*N*4^L), Runtime 446ms
  • + *
  • Space Complexity: O(K*L), Memory 44.81MB
  • + *
  • Note: Refer to answer
  • + */ +class Solution { + + class TrieNode { + Map children = new HashMap<>(); + String word = null; + } + + public List findWords(char[][] board, String[] words) { + TrieNode root = buildTrie(words); + List result = new ArrayList<>(); + + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (root.children.containsKey(board[i][j])) { + TrieNode node = root.children.get(board[i][j]); + findWord(board, i, j, node, result); + } + } + } + + return result; + } + + private TrieNode buildTrie(String[] words) { + TrieNode root = new TrieNode(); + + for (String word : words) { + TrieNode node = root; + for (char c : word.toCharArray()) { + node = node.children.computeIfAbsent(c, k -> new TrieNode()); + } + node.word = word; + } + return root; + } + + private int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; + + private void findWord(char[][] board, int r, int c, TrieNode node, List result) { + if (node.word != null) { + result.add(node.word); + node.word = null; + } + + char letter = board[r][c]; + board[r][c] = '#'; + + for (int[] direction : directions) { + int nr = r + direction[0]; + int nc = c + direction[1]; + + if (nr < 0 || nr > board.length - 1 || nc < 0 || nc > board[0].length - 1) { + continue; + } + if (node.children.containsKey(board[nr][nc])) { + TrieNode nextNode = node.children.get(board[nr][nc]); + findWord(board, nr, nc, nextNode, result); + } + } + + board[r][c] = letter; + } + +} +