TIME O (n); SPACE O (1)
A common requirement of enumerating a list is that you do this in O (n) time and O (1) space. This excludes recursion or stack or temporary array (what if K == n?) Etc. Therefore, the challenge here is to change the in-place reversal algorithm to account for factor K
Instead of K
I use dist
for distance.
Here is a simple in-place reversal algorithm: use three pointers to view the list: b
to point to the title of the new list; c
to indicate the moving head of the raw list; a
to facilitate the exchange between b
and c
.
A->B->C->D->E->F->G->H->I->J->L
To convert the simpleReverse
algorithm to the simpleReverse
algorithm, follow these steps:
1] After reversing the first fragment, set head
to b
; head
is a constant heading for the resulting list.
2] for all other pieces, set tail.next
to b
; recall that b
is the head of the part just processed.
some other details:
3] If the list has one or more nodes, or dist 1 or less, then return the list without processing.
4] use the cnt
counter to track when dist
consecutive nodes have been canceled.
5] use the tail
variable to track the entire processed fragment and tmp
to track the tail of the processed fragment.
6] note that before processing the piece, the head, which should become its tail, is the first node that you encounter: so set it to tmp
, which is a temporary tail.
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; } }