LeetCode 0947. Most Stones Removed with Same Row or Column Solution in Java, C++, Python & More | Explanation + Code

CoderIndeed
0
0947. Most Stones Removed with Same Row or Column

Description

On a 2D plane, we place n stones at some integer coordinate points. Each coordinate point may have at most one stone.

A stone can be removed if it shares either the same row or the same column as another stone that has not been removed.

Given an array stones of length n where stones[i] = [xi, yi] represents the location of the ith stone, return the largest possible number of stones that can be removed.

 

Example 1:

Input: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
Output: 5
Explanation: One way to remove 5 stones is as follows:
1. Remove stone [2,2] because it shares the same row as [2,1].
2. Remove stone [2,1] because it shares the same column as [0,1].
3. Remove stone [1,2] because it shares the same row as [1,0].
4. Remove stone [1,0] because it shares the same column as [0,0].
5. Remove stone [0,1] because it shares the same row as [0,0].
Stone [0,0] cannot be removed since it does not share a row/column with another stone still on the plane.

Example 2:

Input: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
Output: 3
Explanation: One way to make 3 moves is as follows:
1. Remove stone [2,2] because it shares the same row as [2,0].
2. Remove stone [2,0] because it shares the same column as [0,0].
3. Remove stone [0,2] because it shares the same row as [0,0].
Stones [0,0] and [1,1] cannot be removed since they do not share a row/column with another stone still on the plane.

Example 3:

Input: stones = [[0,0]]
Output: 0
Explanation: [0,0] is the only stone on the plane, so you cannot remove it.

 

Constraints:

  • 1 <= stones.length <= 1000
  • 0 <= xi, yi <= 104
  • No two stones are at the same coordinate point.

Solutions

Solution 1: Union-Find

We can use a union-find data structure to maintain the relationships between stones. If two stones are in the same row or column, we consider them to be connected and use the union-find to link them together. In the end, we count how many connected components there are in the union-find, which corresponds to the number of stones that can remain. Therefore, the total number of stones that can be removed is the total number of stones minus the number of stones that can remain. We can also record the number of successful unions during the merge process, which equals the number of stones that can be removed.

The time complexity is O(n2 × Î±(n)), and the space complexity is O(n). Here, n is the number of stones.

PythonJavaC++GoTypeScript
class UnionFind: def __init__(self, n): self.p = list(range(n)) self.size = [1] * n def find(self, x): if self.p[x] != x: self.p[x] = self.find(self.p[x]) return self.p[x] def union(self, a, b): pa, pb = self.find(a), self.find(b) if pa == pb: return False if self.size[pa] > self.size[pb]: self.p[pb] = pa self.size[pa] += self.size[pb] else: self.p[pa] = pb self.size[pb] += self.size[pa] return True class Solution: def removeStones(self, stones: List[List[int]]) -> int: uf = UnionFind(len(stones)) ans = 0 for i, (x1, y1) in enumerate(stones): for j, (x2, y2) in enumerate(stones[:i]): if x1 == x2 or y1 == y2: ans += uf.union(i, j) return ans(code-box)

Solution 2: Union-Find (Optimized)

We can add an offset to the y-coordinates of the stones, allowing us to unify the x-coordinates and y-coordinates. Then, we use a union-find data structure to maintain the relationship between x-coordinates and y-coordinates.

We iterate through each stone, merging its x-coordinate with its y-coordinate.

Finally, we iterate through all the stones again, putting the root node of each stone's x-coordinate into a set. The number of elements in this set represents the number of stones that can remain. Therefore, the total number of stones that can be removed is the total number of stones minus the number of stones that can remain.

The time complexity is O(n × Î±(m)), and the space complexity is O(m). Here, n and m represent the number of stones and the maximum value of the coordinates, respectively.

PythonJavaC++GoTypeScript
class UnionFind: def __init__(self, n): self.p = list(range(n)) self.size = [1] * n def find(self, x): if self.p[x] != x: self.p[x] = self.find(self.p[x]) return self.p[x] def union(self, a, b): pa, pb = self.find(a), self.find(b) if pa == pb: return False if self.size[pa] > self.size[pb]: self.p[pb] = pa self.size[pa] += self.size[pb] else: self.p[pa] = pb self.size[pb] += self.size[pa] return True class Solution: def removeStones(self, stones: List[List[int]]) -> int: m = 10001 uf = UnionFind(m << 1) for x, y in stones: uf.union(x, y + m) return len(stones) - len({uf.find(x) for x, _ in stones})(code-box)

Solution 3: DFS

TypeScriptJavaScript
function removeStones(stones: number[][]): number { const n = stones.length; const g: number[][] = Array.from({ length: n }, () => []); for (let i = 0; i < n; i++) { const [y, x] = stones[i]; for (let j = i + 1; j < n; j++) { if (y === stones[j][0] || x === stones[j][1]) { g[i].push(j); g[j].push(i); } } } const dfs = (i: number) => { const seen = new Set<number>(); let q = [i]; while (q.length) { const qNext: number[] = []; for (const i of q) { if (seen.has(i)) continue; seen.add(i); set.delete(i); qNext.push(...g[i]); } q = qNext; } }; const set = new Set(Array.from({ length: n }, (_, i) => i)); let ans = n; for (const i of set) { dfs(i); ans--; } return ans; }(code-box)

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !