Categorías
Algorithms

LeetCode: la mayoría de las piedras se eliminan con la misma fila o columna (Java)

La solución más sencilla para este problema es el hallazgo sindical. El problema del número de islas puede ayudar a comprender cómo funciona la búsqueda de sindicatos.

La idea básica es que usamos un conjunto disjunto para rastrear cada componente. Siempre que se pueden conectar dos piedras, el número de islas disminuye en uno. El resultado final, el número de movimiento, es el número total de piedras, el número de islas.

Ejemplo 1:

Input: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
Output: 5

Nota:

    1 <= stones.length <= 1000
    0 <= stones[i][j] < 10000

Solución Java 1 – Conjunto disjunto regular

class Solution {
    int[] root = new int[1000]; //value is index
    int result = 0;
 
    public int removeStones(int[][] stones) {
        result = stones.length;
        for(int i=0; i<stones.length; i++){
            root[i]=i;    
        }
 
        for(int i=0; i<stones.length; i++){
            for(int j=i+1; j<stones.length; j++){
                if(stones[i][0]==stones[j][0] || stones[i][1]==stones[j][1]){
                    union(i, j);
                }
            }
        }
 
        return stones.length-result;
    }
 
    public void union(int i, int j){
        int ri = getRoot(i);
        int rj = getRoot(j);
 
        if(ri==rj){
            return;
        }
 
        root[getRoot(i)]=getRoot(j);
        result--;
    }
 
    public int getRoot(int i){
        while(i!=root[i]){
            i=root[i];
        }
 
        return i;
    }
}
  LeetCode - Intercambiar nodos en pares (Java)

La complejidad del tiempo es O (N ^ 2 * log (N)).

Solución Java 2: conjunto disjunto optimizado

class Solution {
    public int removeStones(int[][] stones) {
        DisjointSet ds = new DisjointSet(20000);
        for(int[] stone: stones){
            ds.union(stone[0], stone[1]+10000);
        }
 
        HashSet<Integer> set = new HashSet<>();
        for(int[] stone: stones){
            set.add(ds.find(stone[0]));
        }
 
        return stones.length - set.size();
    }
}
 
class DisjointSet{
    int[] parent;
    public DisjointSet(int size){
        parent = new int[size];
        for(int i=0; i<size; i++){
            parent[i] = i;
        }
    }
 
    public void union(int i, int j){
        parent[find(i)] = find(j);
    }
 
    public int find(int i){
        while(parent[i] != i){
            i = parent[i];
        }
 
        return i;
    }
}

La complejidad del tiempo es log (20000) * N = O (N)

Por Programación.Click

Más de 20 años programando en diferentes lenguajes de programación. Apasionado del code clean y el terminar lo que se empieza. ¿Programamos de verdad?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *