TIME O (n); SPACE O (1)
Un requisito habitual de la inversión de lista es que lo haga en el tiempo O (n) y en el espacio O (1). Esto elimina la recursión o pila o matriz temporal (¿qué pasa si K == n?), Etc. Por lo tanto, el desafío aquí es modificar un algoritmo de inversión in situ para tener en cuenta el factor K
. En lugar de K
uso dist
para la distancia.
Aquí hay un algoritmo de inversión en el lugar simple: utilice tres punteros para recorrer la lista en su lugar: b
para señalar el encabezado de la nueva lista; c
para apuntar al cabezal móvil de la lista no procesada; a
para facilitar el intercambio entre b
y c
.
A->B->C->D->E->F->G->H->I->J->L //original
A<-B<-C<-D E->F->G->H->I->J->L //during processing
^^
| |
b c
`a` is the variable that allow us to move `b` and `c` without losing either of
the lists.
Node simpleReverse(Node n){//n is head
if(null == n || null == n.next)
return n;
Node a=n, b=a.next, c=b.next;
a.next=null; b.next=a;
while(null != c){
a=c;
c=c.next;
a.next=b;
b=a;
}
return b;
}
Convertir el algoritmo simpleReverse
a un algoritmo de chunkReverse
, hacer lo siguiente:
1] Después de la inversión de la primera porción, ajuste head
a b
; head
es el jefe permanente de la lista resultante.
2] para todos los demás fragmentos, establezca tail.next
en b
; recuerde que b
es el encabezado del fragmento recién procesado.
algunos otros detalles:
3] Si la lista tiene uno o menos nodos o el dist es 1 o menos, a continuación, devolver la lista sin procesamiento.
4] utiliza un contador cnt
para rastrear cuando dist
nodos consecutivos se han invertido.
5] usa la variable tail
para rastrear la cola del fragmento recién procesado y tmp
para rastrear la cola del fragmento que se está procesando.
6] observe que antes de que se procese un trozo, su cabeza, que se convertirá en su cola, es el primer nodo con el que se encuentra: así que, configúrelo en tmp
, que es una cola temporal.
public Node reverse(Node n, int dist) {
if(dist<=1 || null == n || null == n.right)
return n;
Node tail=n, head=null, tmp=null;
while(true) {
Node a=n, b=a.right; n=b.right;
a.right=null; b.right=a;
int cnt=2;
while(null != n && cnt < dist) {
a=n; n=n.right; a.right=b; b=a;
cnt++;
}
if(null == head) head = b;
else {
tail.right=b;tail=tmp;
}
tmp=n;
if(null == n) return head;
if(null == n.right) {
tail.right=n;
return head;
}
}//true
}
Would recursividad ayudar? – Coffee
@Adel, sí, claro! – OckhamsRazor
k = 3 sería c-> b-> a-> f-> e-> d-> h-> g? – BLUEPIXY