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;
+ }
+
+}
+