[LeetCode][947. Most Stones Removed with Same Row or Column] It is Literally a Graph: DFS and Union Find

By Long Luo

This article is the solution It is Literally a Graph: DFS and Union Find of Problem 947. Most Stones Removed with Same Row or Column.

Intuition

We can find that this is a graph theory problem with analysis.

Imagine the stone on the 2D coordinate plane as the vertex of the graph, If the x-coord or the y-coord of two stones are the same, there is an edge between them.

This can be show as follows:

947.png

According to the rule that stones can be removed, we should remove those points that are in the same row or column with other points as late as possible. That is, the more points in the same row or column with point A, the later point A should be removed. In this way, we can delete as many points as possible through point A.

It can be found that all vertices in a connected graph can be deleted to only one vertex.

947 2.png

Since these vertices are in a connected graph, all vertices of the connected graph can be traversed by DFS or BFS.

Therefore: the maximum number of stones that can be removed = the number of all stones - the number of connected components.

DFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Solution {
public int removeStones(int[][] stones) {
int n = stones.length;
if (n <= 1) {
return 0;
}

List<Integer>[] graph = new List[n];
for (int i = 0; i < n; i++) {
graph[i] = new ArrayList<>();
}

for (int i = 0; i < n; i++) {
int[] u = stones[i];
for (int j = 0; j < n; j++) {
if (i == j) {
continue;
}

int[] v = stones[j];
if (u[0] == v[0] || u[1] == v[1]) {
graph[i].add(j);
}
}
}

boolean[] visited = new boolean[n];
int ans = 0;

for (int i = 0; i < n; i++) {
if (visited[i]) {
continue;
}

dfs(graph, visited, i);
ans++;
}

return n - ans;
}

private static void dfs(List<Integer>[] graph, boolean[] visited, int start) {

visited[start] = true;

List<Integer> neighbors = graph[start];
for (int x : neighbors) {
if (visited[x]) {
continue;
}

dfs(graph, visited, x);
}
}
}

Analysis

  • Time Complexity: O(n^2).
  • Space Complexity: O(n).

Union Find

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Solution {
public int removeStones(int[][] stones) {
if (stones == null || stones.length <= 1) {
return 0;
}

int n = stones.length;

UnionFind uf = new UnionFind();
for (int[] edge : stones) {
uf.union(edge[0] + 10001, edge[1]);
}

return n - uf.getCount();
}

class UnionFind {
Map<Integer, Integer> parents;
int count;

public UnionFind() {
parents = new HashMap<>();
count = 0;
}

public int getCount() {
return count;
}

public int find(int x) {
if (!parents.containsKey(x)) {
parents.put(x, x);
count++;
}

if (x != parents.get(x)) {
parents.put(x, find(parents.get(x)));
}

return parents.get(x);
}

public void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY) {
return;
}

parents.put(rootX, rootY);
count--;
}
}
}

Analysis

  • Time Complexity: \(O(nlogn)\)
  • Space Complexity: \(O(n)\)

All suggestions are welcome. If you have any query or suggestion please comment below. Please upvote👍 if you like💗 it. Thank you:-)

Explore More Leetcode Solutions. 😉😃💗