LeetCode-765. Parejas tomados de la mano-Análisis y código (Java)

LeetCode-765. Parejas tomados de la mano [Parejas tomados de la mano] -Análisis y código [Java]

1. Tema

N parejas se sientan en 2N asientos seguidos y quieren tomarse de la mano. Calcule el número mínimo de intercambios de asientos para que cada pareja pueda sentarse uno al lado del otro. Se pueden seleccionar dos personas para un intercambio, y pueden ponerse de pie e intercambiar asientos.
Las personas y los asientos están representados por números enteros del 0 al 2N-1. Los amantes están numerados en secuencia. El primer par es (0, 1), el segundo par es (2, 3), y así sucesivamente. El último par es ( 2N-2, 2N-1).
La fila de asientos inicial [i] de estas parejas está determinada por la persona que se sentó inicialmente en el asiento i-ésimo.

Ejemplo 1:

输入: row = [0, 2, 1, 3]
输出: 1
解释: 我们只需要交换row[1]和row[2]的位置即可。

Ejemplo 2:

输入: row = [3, 2, 0, 1]
输出: 0
解释: 无需交换座位,所有的情侣都已经可以手牵手了。

Descripción:

  • len (fila) es un número par y el valor está en el rango [4, 60].
  • Se puede garantizar que row es una permutación completa de la secuencia 0 ... len (row) -1.

Fuente: LeetCode (LeetCode)
Enlace: https://leetcode-cn.com/problems/couples-holding-hands Los
derechos de autor son propiedad de LeetCode . Para reimpresiones comerciales, comuníquese con la autorización oficial. Para reimpresiones no comerciales, indique la fuente.

Dos, análisis y código

1. Combinar

(1) Pensando

Tomando a cada pareja como un punto, conectando a los dos que actualmente están sentados en el par de asientos como un lado. Según el significado de la pregunta, todos eventualmente formarán uno o más bucles de cambio de asiento.
Utilice el conjunto de búsqueda de unión para registrar estos ciclos, y el número de intercambios necesarios para cada componente conectado es el número de pares de pares entre ellos-1.

(2) Código

class Solution {
    
    
    public int minSwapsCouples(int[] row) {
    
    
        int n = row.length, m = n >> 1, ans = 0;
        int[] parent = new int[m];//并查集初始化
        for (int i = 0; i < m; i++)
            parent[i] = i;

        for (int i = 0; i < n;) {
    
    //关联目前坐在连续座位上的人
            union(parent, row[i++] >> 1, row[i++] >> 1);
        }

        Map<Integer, Integer> map = new HashMap<>();//统计各连通分量中的对数
        for (int i = 0; i < m; i++) {
    
    
            int p = find(parent, i);
            map.put(p, map.getOrDefault(p, 0) + 1);
        }
        Iterator iter = map.entrySet().iterator();
        while (iter.hasNext()) {
    
    
            Map.Entry<Integer, Integer> entry = (Map.Entry)iter.next();
            ans += entry.getValue() - 1;//需要交换的次数为联通分量中对数 - 1
        }
        return ans;
    }

    public int find(int[] parent, int p) {
    
    
        if (parent[p] != p)
            parent[p] = find(parent, parent[p]);
        return parent[p];
    }

    public void union(int[] parent, int p1, int p2) {
    
    
        parent[find(parent, p2)] = find(parent, p1);
    }
}

(3) Resultados

Tiempo de ejecución: 1 ms, superando al 27,22% de los usuarios
en todas las presentaciones de Java ; consumo de memoria: 36 MB, superando al 30,64% de los usuarios en todas las presentaciones de Java.

Tres, otro

Nada.

Supongo que te gusta

Origin blog.csdn.net/zml66666/article/details/113853662
Recomendado
Clasificación