|
| 1 | +package stevesun.algorithms; |
| 2 | + |
| 3 | +import stevesun.common.classes.ListNode; |
| 4 | + |
| 5 | +/** |
| 6 | + * Given a singly linked list L: L0→L1→…→Ln-1→Ln, |
| 7 | + reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… |
| 8 | +
|
| 9 | + You must do this in-place without altering the nodes' values. |
| 10 | +
|
| 11 | + For example, |
| 12 | + Given {1,2,3,4}, reorder it to {1,4,2,3}. |
| 13 | + */ |
| 14 | +public class ReorderList { |
| 15 | + |
| 16 | + public void reorderList(ListNode head) { |
| 17 | + if (head == null || head.next == null) { |
| 18 | + return; |
| 19 | + } |
| 20 | + /* first we use two pointers to separate this list into two parts */ |
| 21 | + ListNode slowNode = head, fastNode = head; |
| 22 | + while (fastNode.next != null) { |
| 23 | + fastNode = fastNode.next; |
| 24 | + if (fastNode.next != null) { |
| 25 | + fastNode = fastNode.next; |
| 26 | + } else { |
| 27 | + break; |
| 28 | + } |
| 29 | + slowNode = slowNode.next; |
| 30 | + } |
| 31 | + // two sublist heads |
| 32 | + ListNode head1 = head, head2 = slowNode.next; |
| 33 | + // detach the two sublists; |
| 34 | + slowNode.next = null; |
| 35 | + |
| 36 | + // reverse the second sublist |
| 37 | + ListNode cur = head2, post = cur.next; |
| 38 | + cur.next = null; |
| 39 | + while (post != null) { |
| 40 | + ListNode temp = post.next; |
| 41 | + post.next = cur; |
| 42 | + cur = post; |
| 43 | + post = temp; |
| 44 | + } |
| 45 | + head2 = cur;// the new head of the reversed sublist |
| 46 | + |
| 47 | + // merge the two sublists as required |
| 48 | + ListNode p = head1, q = head2; |
| 49 | + while (q != null) { |
| 50 | + ListNode temp1 = p.next; |
| 51 | + ListNode temp2 = q.next; |
| 52 | + p.next = q; |
| 53 | + q.next = temp1; |
| 54 | + p = temp1; |
| 55 | + q = temp2; |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | +} |
0 commit comments