Skip to content

Commit 7f100e6

Browse files
authored
Solve 9th week problems (DaleStudy#164)
1 parent 467caf0 commit 7f100e6

File tree

5 files changed

+273
-0
lines changed

5 files changed

+273
-0
lines changed

clone-graph/bky373.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
// Definition for a Node.
3+
class Node {
4+
public int val;
5+
public List<Node> neighbors;
6+
public Node() {
7+
val = 0;
8+
neighbors = new ArrayList<Node>();
9+
}
10+
public Node(int _val) {
11+
val = _val;
12+
neighbors = new ArrayList<Node>();
13+
}
14+
public Node(int _val, ArrayList<Node> _neighbors) {
15+
val = _val;
16+
neighbors = _neighbors;
17+
}
18+
}
19+
*/
20+
21+
/*
22+
* time: O(N+M), where N is the number of nodes and M is the number of edges.
23+
* space: O(N), N is the space for the `visited` hash map.
24+
*/
25+
class Solution {
26+
private Map<Node, Node> visited = new HashMap<>();
27+
28+
public Node cloneGraph(Node node) {
29+
if (node == null) {
30+
return node;
31+
}
32+
33+
if (visited.containsKey(node)) {
34+
return visited.get(node);
35+
}
36+
37+
Node cloned = new Node(node.val, new ArrayList());
38+
visited.put(node, cloned);
39+
40+
for (Node neighbor : node.neighbors) {
41+
cloned.neighbors.add(cloneGraph(neighbor));
42+
}
43+
return cloned;
44+
}
45+
}

course-schedule/bky373.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* time: O(V + E), where V is the number of courses (vertices) and E is the number of prerequisites (edges).
3+
* 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.
4+
*/
5+
class Solution {
6+
7+
Map<Integer, List<Integer>> courseToPrerequisites = new HashMap<>();
8+
Set<Integer> traversing = new HashSet<>();
9+
Set<Integer> finished = new HashSet<>();
10+
11+
public boolean canFinish(int numCourses, int[][] prerequisites) {
12+
for (int[] prerequisite : prerequisites) {
13+
courseToPrerequisites.computeIfAbsent(prerequisite[0], key -> new ArrayList<>())
14+
.add(prerequisite[1]);
15+
}
16+
17+
for (int i = 0; i < numCourses; i++) {
18+
if (!dfs(i)) {
19+
return false;
20+
}
21+
}
22+
return true;
23+
}
24+
25+
private boolean dfs(int course) {
26+
if (traversing.contains(course)) {
27+
return false;
28+
}
29+
if (finished.contains(course)) {
30+
return true;
31+
}
32+
33+
traversing.add(course);
34+
if (courseToPrerequisites.containsKey(course)) {
35+
List<Integer> requisites = courseToPrerequisites.get(course);
36+
for (int req : requisites) {
37+
if (!dfs(req)) {
38+
return false;
39+
}
40+
}
41+
}
42+
traversing.remove(course);
43+
finished.add(course);
44+
return true;
45+
}
46+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* time:
3+
* - add: O(N)
4+
* - search: O(N)
5+
* - N is the length of the word.
6+
* space: O(M)
7+
* - M is the number of nodes.
8+
*/
9+
public class WordDictionary {
10+
11+
private Node root;
12+
13+
public WordDictionary() {
14+
root = new Node();
15+
}
16+
17+
public void addWord(String word) {
18+
Node node = root;
19+
for (char ch : word.toCharArray()) {
20+
if (!node.subNodes.containsKey(ch)) {
21+
node.subNodes.put(ch, new Node());
22+
}
23+
node = node.subNodes.get(ch);
24+
}
25+
node.isEndOfWord = true;
26+
}
27+
28+
public boolean search(String word) {
29+
return helper(root, word);
30+
}
31+
32+
public boolean helper(Node node, String word) {
33+
for (int i = 0; i < word.length(); i++) {
34+
char ch = word.charAt(i);
35+
if (!node.subNodes.containsKey(ch)) {
36+
if (ch == '.') {
37+
for (char x : node.subNodes.keySet()) {
38+
Node child = node.subNodes.get(x);
39+
if (helper(child, word.substring(i + 1))) {
40+
return true;
41+
}
42+
}
43+
}
44+
return false;
45+
} else {
46+
node = node.subNodes.get(ch);
47+
}
48+
}
49+
return node.isEndOfWord;
50+
}
51+
52+
private class Node {
53+
54+
Map<Character, Node> subNodes = new HashMap<>();
55+
boolean isEndOfWord;
56+
}
57+
58+
}

number-of-islands/bky373.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* time: O(M * N)
3+
* - M is the number of rows
4+
* - N is the number of columns
5+
* space: O(min(M, N))
6+
* - M is the number of rows
7+
* - N is the number of columns
8+
* in worst case where the grid is filled with lands, the size of queue can grow up to min(𝑀,𝑁).
9+
*/
10+
class Solution {
11+
12+
private char[][] grid;
13+
14+
public int numIslands(char[][] grid) {
15+
this.grid = grid;
16+
int numOfIslands = 0;
17+
18+
for (int i = 0; i < grid.length; i++) {
19+
for (int j = 0; j < grid[0].length; j++) {
20+
if (grid[i][j] == '1') {
21+
numOfIslands++;
22+
bfs(i, j);
23+
}
24+
}
25+
}
26+
return numOfIslands;
27+
}
28+
29+
private void bfs(int i, int j) {
30+
Queue<Integer> que = new LinkedList<>();
31+
que.add(i);
32+
que.add(j);
33+
grid[i][j] = 0;
34+
35+
int[] yDir = {0, -1, 0, 1};
36+
int[] xDir = {1, 0, -1, 0};
37+
38+
while (!que.isEmpty()) {
39+
int y = que.poll();
40+
int x = que.poll();
41+
42+
for (int d = 0; d < 4; d++) {
43+
int ny = y + yDir[d];
44+
int nx = x + xDir[d];
45+
46+
if (ny < 0 || ny >= grid.length || nx < 0 || nx >= grid[0].length) {
47+
continue;
48+
}
49+
50+
if (grid[ny][nx] == '1') {
51+
grid[ny][nx] = '0';
52+
que.add(ny);
53+
que.add(nx);
54+
}
55+
}
56+
}
57+
}
58+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* time: O(M*N)
3+
* space: O(M*N)
4+
* - M is the number of rows
5+
* - N is the number of columns
6+
*/
7+
class Solution {
8+
9+
int[][] heights;
10+
int rLen;
11+
int cLen;
12+
int[] rDirs = {0, -1, 0, 1};
13+
int[] cDirs = {1, 0, -1, 0};
14+
15+
public List<List<Integer>> pacificAtlantic(int[][] heights) {
16+
this.heights = heights;
17+
this.rLen = heights.length;
18+
this.cLen = heights[0].length;
19+
20+
boolean[][] pacific = new boolean[rLen][cLen];
21+
boolean[][] atlantic = new boolean[rLen][cLen];
22+
23+
for (int i = 0; i < rLen; i++) {
24+
dfs(i, 0, pacific);
25+
dfs(i, cLen - 1, atlantic);
26+
}
27+
28+
for (int i = 0; i < cLen; i++) {
29+
dfs(0, i, pacific);
30+
dfs(rLen - 1, i, atlantic);
31+
}
32+
33+
List<List<Integer>> both = new ArrayList<>();
34+
for (int i = 0; i < rLen; i++) {
35+
for (int j = 0; j < cLen; j++) {
36+
if (pacific[i][j] && atlantic[i][j]) {
37+
both.add(List.of(i, j));
38+
}
39+
}
40+
}
41+
return both;
42+
}
43+
44+
private void dfs(int r, int c, boolean[][] visited) {
45+
visited[r][c] = true;
46+
47+
for (int d = 0; d < 4; d++) {
48+
int nr = r + rDirs[d];
49+
int nc = c + cDirs[d];
50+
51+
if (nr < 0 || nr > rLen - 1 || nc < 0 || nc > cLen - 1) {
52+
continue;
53+
}
54+
55+
if (visited[nr][nc]) {
56+
continue;
57+
}
58+
59+
if (heights[nr][nc] < heights[r][c]) {
60+
continue;
61+
}
62+
63+
dfs(nr, nc, visited);
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)