1. Imprima una lista desde la cola hasta la cabeza
Introducir una lista, la lista devuelta por la orden desde el extremo de cabeza de un ArrayList
mi solución
Esta cuestión es muy simple, la lista puede que deberá adoptar elementos de la matriz no subíndice que tienen, una lista sólo desde el principio a un elemento de desplazamiento, los elementos cero add unshift a la matriz a través del método de matriz, tal secuencia es desde la cola hasta la cabeza.
function printListFromTailToHead(head)
{
var array=[]
var current=head
while(current){
array.unshift(current.val)
current = current.next
}
return array
}
2. El nodo de entrada del anillo de lista enlazada
mi solución
Por supuesto, estar equivocado, de principio a fin de atravesar los nodos, añadir un atributo al nodo, si hay un anillo, entonces habrá un punto de unión antes del nodo que se está atravesando, entonces el nodo tendrá la propiedad añadido . Pero para hacerlo, destruyó los datos originales
otros análisis
1. Conjunto de dos punteros, rápido y lento, puntero del puntero rápida es la velocidad dos veces más lento. Si hay un anillo, entoncesAmbos se reunirán en un nodo de anillo.
2. A continuación, el puntero de cabeza a un nodo de inicio, el otro nodo de inicio en el encuentro, pero velocidad uniforme,Ambos nodos se cumple anillo de nuevo de entrada
demostrar
1. Indicador del ayuno cada dar dos pasos, cada paso lento puntero lento, cuando el puntero lentamente en el anillo, está persiguiendo a un problema físico, los dos sin duda se cumplirá.
2. Como se muestra arriba, la longitud de AC asumió una, CB longitud b, la longitud BC c. Cuando se reunió:
-
Viajó puntero rápido a un + k (b + c) + b, k> = 1
-
puntero lenta viajó a a + b.
Hay sólo dos puntos de la fórmula:
- k> = 1 es constante, si un bucle rápido alrededor falló para ponerse al día fue lento, tanto en la misma distancia que el tiempo transcurrido, que es contraria a la de dos velocidades diferentes
- Ciertamente no lenta en circuito, aunque lento alrededor de un anillo, rápido, sin duda en torno a los dos anillos que ya se reunieron
Por lo tanto, 2 (a + b) = a + k (b + c) + b, k> = 1, mediante el cual un = (k-1) (b + c) + C, K> = 1. Una expresión de significado es: la lista de cabeza del anillo de la distancia al punto de encuentro = distancia de entrada al anillo de entrada + (k-1) de la longitud de los anillos. Dos punteros misma velocidad, a través de la misma distancia en la misma longitud de tiempo, a partir del puntero de punto A se reunirá y el punto de salida de la aguja C alrededor del anillo en la entrada del anillo.
function EntryNodeOfLoop(pHead){
var fast = pHead
var slow = pHead
while(fast!=null&&fast.next!=null){
slow = slow.next
fast = fast.next.next
if(slow == fast){
let p = pHead
while(p!=slow){
p = p.next
slow = slow.next
}
return p
}
}
return null
}
suplemento
La longitud del bucle : el punto B en el anillo, las nuevas variables de posición de grabación, punteros Desde este punto, mientras caminaba punto de determinación del recuento y el registro actual, cuando la parte posterior registro en el momento en que la cuenta es la longitud del bucle.
La longitud de la lista : se conoce la longitud del bucle, es el valor de una más la longitud de la lista.
3. Retire la lista de nodos duplicados
En una lista enlazada ordenados nodos duplicados, eliminar la lista de nodos duplicados, el nodo no conserva repetido, devuelve la lista de punteros de cabeza. Por ejemplo, la lista 1-> 2-> 3-> 3-> 4-> 4-> 5 se trata 1-> 2-> 5
mi solución
Erróneo extravagante, sino también profundizado la comprensión de la estructura de la lista, tales como la forma de eliminar la lista (¿quién habría pensado que estaba buscando un día a esta pregunta)
otros análisis
1. ¿Cómo eliminar una lista de nodos vinculados? Antes de que el siguiente puntero es un cambio de puntero por un nodo.
- Así que esta pregunta que desee eliminar nodos, asegúrese de registrar un nodo variable intermedia antes de la act nodo actual , aquí ajustar a pre.
- Además, se considera un caso especial del primer nodo y el segundo nodo se repite, entonces el primer nodo de cómo eliminar? No es antes del cruce, ¡ah! Así que desea establecer un nodo principal, nos ayudan a eliminar el primer nodo
2.Pre acción puntero: es el nodo antes del nodo actual, cambiar el puntero para saltar el punto de nodo a un punto duplicado no se repetirá . Fue frente a la cual se Nodo? Eso sí, no repetir el punto determinado momento, por lo que cuando hacemos travesía no repetición al siguiente punto del tiempo, el puntero previo al punto de la línea.
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function deleteDuplication(pHead)
{
var Head = new ListNode(0) //设置一个头结点
Head.next = pHead //指向第一个结点
var pre = Head
var cur = pHead
while(cur != null){
if(cur.next!=null&&cur.val == cur.next.val){
while(cur.next!=null&&cur.val == cur.next.val){
cur = cur.next
}
pre.next = cur.next
cur = cur.next
}else{
pre = pre.next
cur = cur.next
}
}
return Head.next
}
3. Los problemas de procesamiento transfronterizo
inicialmente I escribieron las siguientes condiciones de ciclo, situado en el bucle más externo determina si un nodo siguiente está vacío, una descripción del nodo actual es el último nodo tan fuera del bucle. Pero fue entonces cuando la lista está vacía va a error, así que esto no es correcto.
while(cur.next != null){
if(cur.val == cur.next.val){
while(cur.val == cur.next.val){
4.Pre actualización: Creo que durante mucho tiempo, probablemente estúpida.
Cuando encuentran los siguientes nodos duplicados, nos encontramos con un nodo y luego repetir el último que hay que hacer es borrar! Por lo tanto, el cambio de la siguiente puntero de la pre
pre.next = cur.next
Cuando se encuentra el siguiente nodo y el nodo actual no es el mismo, pre es una posición frontal (en las posiciones de nodo son no determinado a punto de repetición) no se actualiza para el punto último en duplicado
pre = pre.next
4. replicación lista compleja
Una lista de entrada compleja (cada nodo tiene un valor de nodo, y dos punteros, uno de puntero al siguiente nodo, un puntero especial a cualquier otro nodo), devuelve un valor después de la cabeza de la replicación lista compleja. (Tenga en cuenta que los resultados de salida no vuelven referencia de nodo de parámetros, de lo contrario el programa volverá preguntas condenados vacíos directamente)
mi solución
¿Cómo puedo Solución
otros análisis
Tres pasos
método para probar la seguridad dado muy intuitiva, dibujar un mapa, un pensamiento claro, escribir el código es realmente muy bueno
function Clone(pHead)
{
if(pHead == null) return null
let pNode = pHead
//第一步:复制每个结点,把新结点插入旧结点的后面
while(pNode){
let cloneNode = new RandomListNode(pNode.label)
cloneNode.next = pNode.next //注意赋值顺序
pNode.next = cloneNode
pNode = cloneNode.next
}
//第二步:旧结点的random复制
pNode = pHead
while(pNode){
if(pNode.random){ //这个判断要有
pNode.next.random = pNode.random.next
}
pNode = pNode.next.next
}
//第三步:拆分链表
pNode = pHead
let cloneHead = pHead.next
let cloneNode = cloneHead
while(pNode){
pNode.next = pNode.next.next
if(cloneNode.next){
cloneNode.next = cloneNode.next.next
}
pNode = pNode.next
cloneNode = cloneNode.next
}
return cloneHead
}
Hashing
está representado por una tabla hash la cartografía de la relación entre viejos y nuevos nodos: Clave es un nodo de edad, el valor es el nuevo nodo. Aquí hay que utilizar la nueva estructura de datos del mapa ES6: objeto especial, puede ser un objetivo clave.
- Primer paso: Copia el valor del puntero de edad y el siguiente nodo, con una relación de proyección de mapa almacenado entre los antiguos y nuevos nodos
- Segundo paso: la obtención de un nuevo nodo correspondiente al nodo a través del mapa viejo, el nuevo puntero se actualiza nodo de azar
function Clone(pHead)
{
if(pHead == null) return null
let map = new Map()
let pNode = pHead
//新链表的头
let cloneHead = new RandomListNode(pHead.label)
let cloneNode = cloneHead
map.set(pNode,cloneNode) //先把两个头放进去,代码会简洁一点
//第一次遍历:复制旧结点的值和next
while(pNode){
//创建新结点
if(pNode.next){ //这个判断一定要有
cloneNode.next = new RandomListNode(pNode.next.label)
}else{
cloneNode.next = null
}
cloneNode = cloneNode.next
pNode = pNode.next
map.set(pNode,cloneNode) //结点对存入map中
}
//第二次遍历:复制random指针
pNode = pHead
while(pNode){
if(pNode.random){
//map的get方法:由键取值
map.get(pNode).random = map.get(pNode.random)
}
pNode = pNode.next
}
return cloneHead
}
Los árboles de búsqueda binaria y la lista doblemente enlazada
Introduzca un árbol de búsqueda binaria, el árbol de búsqueda binaria convertida en una lista doblemente enlazada ordenadas. Requisitos no pueden crear ningún nuevo nodo, punto sólo para ajustar el puntero del nodo del árbol.
mi solución
Para ordenar los resultados ilustran el uso orden previo, que es el único pequeño a grande. Atravesando los nodos creados al mismo tiempo, y cambiar el puntero a. Así que realmente no lo hacen
otros análisis
Se gana el siguiente análisis, que es necesario registrar el resumen del punto de máxima unión del subárbol más a la izquierda y el subárbol derecho. Tal raíz y enlaces, todo el árbol se convertirá mejor.
Grabación de un puntero a pre el presente documento.
recursividad
- Las funciones de conversión función clara.
Introduzca: Introduzca el nodo raíz de un árbol de búsqueda binaria.
Proceso: para convertirlo en una lista doblemente enlazada ordenada.
Salida: Devuelve el nodo de cabecera de la lista enlazada. - Borrar la función última variable miembro.
para el registro de la última final de la lista de nodos actual. - procedimiento recursivo clara.
proceso recursivo es equivalente a seguir con el fin de atravesar toda la descomposición de árboles en numerosos árboles, y luego se transformaron en corto corta lista doblemente enlazada. Allá del final de la grabación del reciclaje total de la lista, a continuación, la lista de estas pequeñas piezas añadidas a un extremo después de otro.
código recursivo es realmente un dolor de cabeza, al principio de mi código es la siguiente
function Convert(pRootOfTree)
{
if(pRootOfTree == null) return null
let last = null
ConvertCore(pRootOfTree,last)
let pHead = pRootOfTree
while(pHead.left){
pHead = pHead.left
}
return pHead
}
function ConvertCore(root,last){
if(root == null) return
ConvertCore(root.left,last)
root.left = last
if(last) last.right = root
last = root
ConvertCore(root.right,last)
}
Dado que
la estructura que se muestra a continuación se puede ver los cuatro nodos 4,6,8,12 hicieron.
No se pudo encontrar una causa del error, el código siguiente en un normal, supongo que es la última actualización en cuestión.
function Convert(pRootOfTree)
{
if(pRootOfTree == null) return null
let last = null
ConvertCore(pRootOfTree,last)
let pHead = pRootOfTree
while(pHead.left){
pHead = pHead.left
}
return pHead
}
function ConvertCore(root,last){
if(root == null) return
if(root.left){
last = ConvertCore(root.left,last)
}
root.left = last
if(last) last.right = root
last = root
if(root.right){
last = ConvertCore(root.right,last)
}
return last
}
No recursiva
secuencia recursiva simultánea, requiere un pre puntos puntero de registro en el extremo del nodo de lista enlazada actual. Realmente entender mucho mejor que el recursiva.
function Convert(pRootOfTree)
{
if (pRootOfTree == null) return null
let stack = [];
let node = pRootOfTree
let pre = null
let head = null
while (stack.length || node) {
//一直遍历到树的最左边也就是最小值
if (node) {
stack.push(node);
node = node.left;
} else {
//最左子结点出栈
let top = stack.pop()
//pre为null说明top就是最左子结点就是链表的头
if (pre == null) {
head = top
} else { //pre不为null,那就需要top的左右指针赋值
pre.right = top
}
top.left = pre
pre = top //链表最后结点就是top了
node = top.right
}
}
return head
}
6. Las dos listas de nodos común
Dos listas de entrada, encontrar su primer nodo común. (Tenga en cuenta que debido a los datos de entrada es una lista enlazada, por lo que se muestra un error de los datos de prueba en otras maneras de asegurar que los datos de entrada es correcta)
mi solución
puntero del doble, los punteros ir una cadena larga, como la longitud restante de la lista corta vienen de la misma cadena, corta comenzó a caminar puntero, dos punteros siguiente determina si el mismo es necesario.
Obviamente, para obtener la longitud de las dos listas.
function FindFirstCommonNode(pHead1, pHead2)
{
if(pHead1 == null||pHead2 == null)
return null
let gap = GetListLength(pHead1)- GetListLength(pHead2)
let short = pHead1,long = pHead2
//要知道哪个是长链表
if(gap>0){
short = pHead2
long = pHead1
}
//long先走
while(gap--){
long = long.next
}
//开始一起走
while(long!=null){
if(long==short){
return long
}
long = long.next
short = short.next
}
}
//获取链表长
function GetListLength(pHead){
let cur = pHead
let len = 0
while(cur){
len++
cur = cur.next
}
return len
}