TIME O (n); SPACE O (1)
Un normale requisito di inversione dell'elenco è che lo si fa nel tempo O (n) e nello spazio O (1). Questo elimina ricorsione o stack o array temporaneo (cosa succede se K == n?), Ecc. Quindi la sfida qui è modificare un algoritmo di inversione sul posto per tenere conto del fattore K
. Invece di K
io uso dist
per la distanza.
Ecco un semplice algoritmo di inversione sul posto: utilizzare tre puntatori per spostare l'elenco sul posto: b
in modo che punti all'inizio del nuovo elenco; c
per indicare la testa mobile dell'elenco non elaborato; a
per facilitare lo scambio tra b
e 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;
}
Per convertire il simpleReverse
algoritmo per un chunkReverse
algoritmo, do seguente:
1] Dopo l'inversione primo blocco, impostare head
a b
; head
è il capo permanente dell'elenco risultante.
2] per tutti gli altri blocchi, impostare tail.next
su b
; ricorda che b
è il capo del blocco appena elaborato.
qualche altro dettaglio:
3] Se la lista ha una o un minor numero di nodi o il dist è 1 o meno, per poi tornare alla lista senza elaborazione.
4] utilizzare un contatore cnt
per rintracciare quando i nodi consecutivi sono stati invertiti dist
.
5] utilizzare la variabile tail
per tracciare la coda del blocco appena elaborato e tmp
per tracciare la coda del blocco in elaborazione.
6] si noti che prima che un blocco venga elaborato, è la testa, che è destinata a diventare la coda, è il primo nodo che si incontra: quindi, impostarlo su tmp
, che è una coda temporanea.
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
}
Sarebbe ricorsione aiutare? – Coffee
@Adel si certo! – OckhamsRazor
k = 3 sarebbe c-> b-> a-> f-> e-> d-> h-> g? – BLUEPIXY