diff --git a/clone-graph/bky373.java b/clone-graph/bky373.java new file mode 100644 index 000000000..c6da0f92e --- /dev/null +++ b/clone-graph/bky373.java @@ -0,0 +1,45 @@ +/* +// Definition for a Node. +class Node { + public int val; + public List neighbors; + public Node() { + val = 0; + neighbors = new ArrayList(); + } + public Node(int _val) { + val = _val; + neighbors = new ArrayList(); + } + public Node(int _val, ArrayList _neighbors) { + val = _val; + neighbors = _neighbors; + } +} +*/ + +/* + * time: O(N+M), where N is the number of nodes and M is the number of edges. + * space: O(N), N is the space for the `visited` hash map. + */ +class Solution { + private Map visited = new HashMap<>(); + + public Node cloneGraph(Node node) { + if (node == null) { + return node; + } + + if (visited.containsKey(node)) { + return visited.get(node); + } + + Node cloned = new Node(node.val, new ArrayList()); + visited.put(node, cloned); + + for (Node neighbor : node.neighbors) { + cloned.neighbors.add(cloneGraph(neighbor)); + } + return cloned; + } +} diff --git a/course-schedule/bky373.java b/course-schedule/bky373.java new file mode 100644 index 000000000..dc94a85f8 --- /dev/null +++ b/course-schedule/bky373.java @@ -0,0 +1,46 @@ +/* + * time: O(V + E), where V is the number of courses (vertices) and E is the number of prerequisites (edges). + * space: O(V + E), where V is for the map and sets and E is for call stacks, which is bounded by the number of courses and prerequisites. + */ +class Solution { + + Map> courseToPrerequisites = new HashMap<>(); + Set traversing = new HashSet<>(); + Set finished = new HashSet<>(); + + public boolean canFinish(int numCourses, int[][] prerequisites) { + for (int[] prerequisite : prerequisites) { + courseToPrerequisites.computeIfAbsent(prerequisite[0], key -> new ArrayList<>()) + .add(prerequisite[1]); + } + + for (int i = 0; i < numCourses; i++) { + if (!dfs(i)) { + return false; + } + } + return true; + } + + private boolean dfs(int course) { + if (traversing.contains(course)) { + return false; + } + if (finished.contains(course)) { + return true; + } + + traversing.add(course); + if (courseToPrerequisites.containsKey(course)) { + List requisites = courseToPrerequisites.get(course); + for (int req : requisites) { + if (!dfs(req)) { + return false; + } + } + } + traversing.remove(course); + finished.add(course); + return true; + } +} diff --git a/design-add-and-search-words-data-structure/bky373.java b/design-add-and-search-words-data-structure/bky373.java new file mode 100644 index 000000000..7df425ec8 --- /dev/null +++ b/design-add-and-search-words-data-structure/bky373.java @@ -0,0 +1,58 @@ +/* + * time: + * - add: O(N) + * - search: O(N) + * - N is the length of the word. + * space: O(M) + * - M is the number of nodes. + */ +public class WordDictionary { + + private Node root; + + public WordDictionary() { + root = new Node(); + } + + public void addWord(String word) { + Node node = root; + for (char ch : word.toCharArray()) { + if (!node.subNodes.containsKey(ch)) { + node.subNodes.put(ch, new Node()); + } + node = node.subNodes.get(ch); + } + node.isEndOfWord = true; + } + + public boolean search(String word) { + return helper(root, word); + } + + public boolean helper(Node node, String word) { + for (int i = 0; i < word.length(); i++) { + char ch = word.charAt(i); + if (!node.subNodes.containsKey(ch)) { + if (ch == '.') { + for (char x : node.subNodes.keySet()) { + Node child = node.subNodes.get(x); + if (helper(child, word.substring(i + 1))) { + return true; + } + } + } + return false; + } else { + node = node.subNodes.get(ch); + } + } + return node.isEndOfWord; + } + + private class Node { + + Map subNodes = new HashMap<>(); + boolean isEndOfWord; + } + +} diff --git a/number-of-islands/bky373.java b/number-of-islands/bky373.java new file mode 100644 index 000000000..89a75a91b --- /dev/null +++ b/number-of-islands/bky373.java @@ -0,0 +1,58 @@ +/* + * time: O(M * N) + * - M is the number of rows + * - N is the number of columns + * space: O(min(M, N)) + * - M is the number of rows + * - N is the number of columns + * in worst case where the grid is filled with lands, the size of queue can grow up to min(𝑀,𝑁). + */ +class Solution { + + private char[][] grid; + + public int numIslands(char[][] grid) { + this.grid = grid; + int numOfIslands = 0; + + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == '1') { + numOfIslands++; + bfs(i, j); + } + } + } + return numOfIslands; + } + + private void bfs(int i, int j) { + Queue que = new LinkedList<>(); + que.add(i); + que.add(j); + grid[i][j] = 0; + + int[] yDir = {0, -1, 0, 1}; + int[] xDir = {1, 0, -1, 0}; + + while (!que.isEmpty()) { + int y = que.poll(); + int x = que.poll(); + + for (int d = 0; d < 4; d++) { + int ny = y + yDir[d]; + int nx = x + xDir[d]; + + if (ny < 0 || ny >= grid.length || nx < 0 || nx >= grid[0].length) { + continue; + } + + if (grid[ny][nx] == '1') { + grid[ny][nx] = '0'; + que.add(ny); + que.add(nx); + } + } + } + } +} diff --git a/pacific-atlantic-water-flow/bky373.java b/pacific-atlantic-water-flow/bky373.java new file mode 100644 index 000000000..e75dce988 --- /dev/null +++ b/pacific-atlantic-water-flow/bky373.java @@ -0,0 +1,66 @@ +/* + * time: O(M*N) + * space: O(M*N) + * - M is the number of rows + * - N is the number of columns + */ +class Solution { + + int[][] heights; + int rLen; + int cLen; + int[] rDirs = {0, -1, 0, 1}; + int[] cDirs = {1, 0, -1, 0}; + + public List> pacificAtlantic(int[][] heights) { + this.heights = heights; + this.rLen = heights.length; + this.cLen = heights[0].length; + + boolean[][] pacific = new boolean[rLen][cLen]; + boolean[][] atlantic = new boolean[rLen][cLen]; + + for (int i = 0; i < rLen; i++) { + dfs(i, 0, pacific); + dfs(i, cLen - 1, atlantic); + } + + for (int i = 0; i < cLen; i++) { + dfs(0, i, pacific); + dfs(rLen - 1, i, atlantic); + } + + List> both = new ArrayList<>(); + for (int i = 0; i < rLen; i++) { + for (int j = 0; j < cLen; j++) { + if (pacific[i][j] && atlantic[i][j]) { + both.add(List.of(i, j)); + } + } + } + return both; + } + + private void dfs(int r, int c, boolean[][] visited) { + visited[r][c] = true; + + for (int d = 0; d < 4; d++) { + int nr = r + rDirs[d]; + int nc = c + cDirs[d]; + + if (nr < 0 || nr > rLen - 1 || nc < 0 || nc > cLen - 1) { + continue; + } + + if (visited[nr][nc]) { + continue; + } + + if (heights[nr][nc] < heights[r][c]) { + continue; + } + + dfs(nr, nc, visited); + } + } +}