Algorithm


Problem Name: 947. Most Stones Removed with Same Row or Column

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.

 
 

Code Examples

#1 Code Example with C Programming

Code - C Programming


void dfs(int **stones, int sz, int p, int *visited, int *n) {
    int r, c, i;
    
    if (visited[p]) return;
    
    visited[p] = 1;

    (*n) ++;
    
    r = stones[p][0];
    c = stones[p][1];
    
    // remove stones on same row
    for (i = 0; i  <  sz; i ++) {
        if (stones[i][0] == r) dfs(stones, sz, i, visited, n);
    }
    
    // remove stones on same col
    for (i = 0; i  <  sz; i ++) {
        if (stones[i][1] == c) dfs(stones, sz, i, visited, n);
    }
    
    //visited[p] = 0;
}
​
int removeStones(int** stones, int stonesSize, int* stonesColSize){
    int n, ans = 0;
    int *visited;
    int i;
    
    visited = calloc(stonesSize, sizeof(int));
    //assert(visited);
    
    for (i = 0; i  <  stonesSize; i ++) {
        n = 0;
        dfs(stones, stonesSize, i, visited, &n);
        if (n) ans += n - 1;
        //printf("%d\n", n);
    }
    
    free(visited);
    
    return ans;
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]

Output

x
+
cmd
5

#2 Code Example with Java Programming

Code - Java Programming


class Solution {
  public int removeStones(int[][] stones) {
    Set<int[]> visited = new HashSet<>();
    int numOfIslands = 0;
    for (int[] stone : stones) {
      if (!visited.contains(stone)) {
        dfs(stones, visited, stone);
        numOfIslands++;
      }
    }
    return stones.length - numOfIslands;
  }
  
  private void dfs(int[][] stones, Set < int[]> visited, int[] stone) {
    visited.add(stone);
    for (int[] st : stones) {
      if ((st[0] == stone[0] || st[1] == stone[1]) && !visited.contains(st)) {
        dfs(stones, visited, st);
      }
    }
  }
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]

Output

x
+
cmd
5

#3 Code Example with Javascript Programming

Code - Javascript Programming


const removeStones = function(stones) {
  const f = new Map()
  let islands = 0
  for (let i = 0; i  <  stones.length; i++) {
    union(stones[i][0], ~stones[i][1]) // row, col
  }
  return stones.length - islands

  function find(x) {
    if (!f.has(x)) {
      islands++
      f.set(x, x)
    }
    if (x != f.get(x)) {
      f.set(x, find(f.get(x)))
    }
    return f.get(x)
  }

  function union(x, y) {
    x = find(x)
    y = find(y)
    if (x !== y) {
      f.set(x, y)
      islands--
    }
  }
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]

Output

x
+
cmd
3

#4 Code Example with Python Programming

Code - Python Programming


class Solution:
    def removeStones(self, stones):
        def dfs(i, j):
            points.discard((i, j))
            for y in rows[i]:
                if (i, y) in points:
                    dfs(i, y)
            for x in cols[j]:
                if (x, j) in points:
                    dfs(x, j)
        points, island, rows, cols = {(i, j) for i, j in stones}, 0, collections.defaultdict(list), collections.defaultdict(list)
        for i, j in stones:
            rows[i].append(j)
            cols[j].append(i)
        for i, j in stones:
            if (i, j) in points:
                dfs(i, j)
                island += 1
        return len(stones) - island
Copy The Code & Try With Live Editor

Input

x
+
cmd
stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]

Output

x
+
cmd
3

#5 Code Example with C# Programming

Code - C# Programming


using System.Collections.Generic;

namespace LeetCode
{
    public class _0947_MostStonesRemovedWithSameRoworColumn
    {
        private const int BOARD_SIZE = 10000;

        public int RemoveStones(int[][] stones)
        {
            var uf = new UnionFind(BOARD_SIZE * 2);

            foreach (var stone in stones)
                uf.Union(stone[0], stone[1] + BOARD_SIZE);

            var set = new HashSet < int>();
            foreach (var stone in stones)
                set.Add(uf.FindParent(stone[0]));
            return stones.Length - set.Count;
        }

        public class UnionFind
        {
            private int[] parents;

            public UnionFind(int size)
            {
                parents = new int[size];
                for (int i = 0; i  <  size; i++)
                    parents[i] = i;
            }

            public int FindParent(int x)
            {
                while (parents[x] != x)
                    x = parents[x];
                return parents[x];
            }

            public void Union(int x, int y)
            {
                parents[FindParent(x)] = FindParent(y);
            }
        }
    }
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
stones = [[0,0]]
Advertisements

Demonstration


Previous
#946 Leetcode Validate Stack Sequences Solution in C, C++, Java, JavaScript, Python, C# Leetcode
Next
#948 Leetcode Bag of Tokens Solution in C, C++, Java, JavaScript, Python, C# Leetcode