17,19 preguntas de LeetCode Top100

17. Combinación de letras del número de teléfono

  • Dada una cadena que contiene solo números del 2 al 9, devuelve todas las combinaciones de letras que pueda representar.
  • La asignación de números a letras se da de la siguiente manera (igual que los botones del teléfono). Tenga en cuenta que 1 no corresponde a ninguna letra.
    Inserte la descripción de la imagen aquí
  • Ejemplo:

Entrada: "23"
Salida: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Explicación: A pesar de lo anterior Las respuestas están organizadas en orden lexicográfico, pero puede elegir el orden en el que se emiten.

② Convierta el problema combinatorio (que requiere varios ciclos) en una multiplicación: la velocidad es inesperadamente rápida.
  • Según el significado del título, si el número es “23”, la última combinación de letras es amable 3 x 3 = 9; si el número es “234”, la última combinación de letras es amable 9 x 3 = 27. Este es un problema de combinación. Debe haber algunos números y se necesitan varias capas de bucles para obtener todas las combinaciones de letras.
  • No hay forma de escribir un bucle multicapa sin conocer el número de números. Así que cámbielo para multiplicar. Cuando la longitud de list1 sea 0, regrese a list2 directamente; de ​​lo contrario, use un bucle de 2 capas para combinar las letras en list1 y list2.
  • De esta manera, las “234”combinaciones de letras correspondientes se pueden combinar en 3 x 3 x 3 = 27multiplicaciones.
  • el código se muestra a continuación:
public List<String> letterCombinations(String digits) {
    
    
    List<String> result = new ArrayList<>();
    if (digits == null || digits.length() == 0) {
    
    
        return result;
    }
    for (int i = 0; i < digits.length(); i++) {
    
    
        result = mul(result, getList(digits.charAt(i) - '0'));
    }
    return result;
}

public List<String> getList(int num) {
    
    
    String digitLetter[] = {
    
    "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    List<String> res = new ArrayList<>();
    for (int i = 0; i < digitLetter[num].length(); i++) {
    
    
        res.add(digitLetter[num].charAt(i) + "");
    }
    return res;
}

public List<String> mul(List<String> list1, List<String> list2) {
    
    
    if (list1.size() == 0 && list2.size() != 0) {
    
    
        return list2;
    }
    List<String> res = new ArrayList<>();
    for (int i = 0; i < list1.size(); i++) {
    
    
        for (int j = 0; j < list2.size(); j++) {
    
    
            res.add(list1.get(i) + list2.get(j));
        }
    }
    return res;
}
③ Usar recursividad
  • Se puede ver en el gráfico dinámico que todas las combinaciones de letras posibles se pueden obtener usando la recursividad.

Backtracking es un algoritmo para encontrar todas las soluciones mediante la exploración de todos los candidatos potenciales. Si la solución candidata resulta no ser una solución (o al menos no la última), el algoritmo de retroceso lo descarta haciendo algunos cambios en el paso anterior, es decir, retrocede y luego vuelve a intentarlo.

  • Cuando la longitud de los dígitos es 0, indica que se ha encontrado la última combinación y se agrega directamente al resultado.
    Inserte la descripción de la imagen aquí
String digitLetter[] = {
    
    "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
List<String> result = new ArrayList<>();

public List<String> letterCombinations(String digits) {
    
    
    if (digits.length() == 0 || digits == null) {
    
    
        return result;
    }
    helper("", digits);
    return result;

}

public void helper(String com, String digits) {
    
    
    if (digits.length() == 0) {
    
    
        result.add(com);
    } else {
    
    
        int index = digits.charAt(0) - '0';
        for (int i = 0; i < digitLetter[index].length(); i++) {
    
    
            helper(com + digitLetter[index].charAt(i), digits.substring(1));
        }
    }
}
④ iteración de la cola
  • Utilice inteligentemente la LinkedListlista doblemente enlazada, elimine las combinaciones que cumplan las condiciones de la cabeza y agregue nuevas combinaciones de la cola.
  • Elimina del encabezado la combinación que cumple las condiciones. La longitud de la combinación debe ser la misma que el índice del número actual. Cuando el índice es 0, la longitud de la combinación es 0, por lo que debe agregarse por adelantado ""; cuando el índice es 1, elimine ( eg: 'a', 'b', 'c') todas las combinaciones de longitud 1 en la cabecera y combínelas con las letras del número actual para formar una nueva combinación, y luego Agrega la cola.
String digitLetter[] = {
    
    "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};

public List<String> letterCombinations(String digits) {
    
    
    LinkedList<String> result = new LinkedList<>();
    if (digits.length() == 0 || digits == null) {
    
    
        return result;
    }
    result.add("");
    for (int i = 0; i < digits.length(); i++) {
    
    
        int index = digits.charAt(i) - '0';
        while (result.peek().length() == i) {
    
    
            String com = result.remove();
            for (int j = 0; j < digitLetter[index].length(); j++) {
    
    
                result.add(com + digitLetter[index].charAt(j));
            }
        }
    }
    return result;
}

19. Elimina el nodo N de la parte inferior de la lista vinculada.

① Descripción del título
  • Dada una lista vinculada, elimine el n-ésimo nodo de la parte inferior de la lista vinculada y devuelva el nodo principal de la lista vinculada.
  • Ejemplo:

Dada una lista vinculada: 1-> 2-> 3-> 4-> 5, y n = 2.
Cuando se elimina el penúltimo nodo, la lista vinculada se convierte en 1-> 2-> 3-> 5.
Explicación: Las n garantías dadas son válidas.

  • Avanzado:
    ¿Puedes intentar usar un escaneo para lograrlo?
② Dos recorridos
  • Un recorrido se usa para obtener la longitud de la lista enlazada, y un recorrido se usa para encontrar la anterior del nodo eliminado y luego actualizar el punto anterior.
  • Después del primer recorrido, si len es el mismo que el índice que se va a eliminar, significa que se elimina el primer nodo, así que siga recto return head.next;.
public ListNode removeNthFromEnd(ListNode head, int n) {
    
    
    int len = 0;
    ListNode p = head;
    while (p != null) {
    
    
        len++;
        p = p.next;
    }
    if (len == n) {
    
    
        return head.next;
    }
    ListNode prev;
    p = head;
    int cur = 0;
    while (p != null) {
    
    
        cur++;
        if (cur == len - n) {
    
    
            prev = p;
            prev.next = prev.next.next;
            break;
        }
        p = p.next;
    }
    return head;
}
③ Travesía única
  • La idea principal: en contraste con la lista, establecemos dos punteros ( firsty second), dejamos que el firstpuntero atraviese el n + 1paso y luego dejamos que Talia mientras atraviesa. En este caso, cuando firstllega el puntero null节点, el secondpuntero está a una distancia de n del primer puntero, por lo que secondla posición del puntero es exactamente esa 倒数第 n 个结点的prev.
  • Características:
    ① Necesita agregar un dummynodo como una nueva cabeza;
    ② El firstpuntero se ejecuta primero, no n pasos, sino n + 1pasos;
    ③ Cuando se ejecuta al mismo tiempo, firstdeténgase cuando el puntero apunte a nulo.
    Inserte la descripción de la imagen aquí
public ListNode removeNthFromEnd(ListNode head, int n) {
    
    
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    ListNode first = dummy, second = dummy;
    for (int i = 1; i <= n + 1; i++) {
    
    
        first = first.next;
    }
    while (first != null) {
    
    
        first = first.next;
        second = second.next;
    }
    second.next = second.next.next;
    return dummy.next;
}

Supongo que te gusta

Origin blog.csdn.net/u014454538/article/details/90400524
Recomendado
Clasificación