Reorder List

Given a singly linked list L: L0→L1→…→Ln-1→Ln,

reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You must do this in-place without altering the nodes’ values.

For example,

Given {1,2,3,4}, reorder it to {1,4,2,3}.

Solution:

  1. /**
  2. * Definition for singly-linked list.
  3. * class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode(int x) {
  7. * val = x;
  8. * next = null;
  9. * }
  10. * }
  11. */
  12. public class Solution {
  13. public void reorderList(ListNode head) {
  14. if (head == null || head.next == null)
  15. return;
  16. // step 1. cut the list to two halves
  17. // prev will be the tail of 1st half
  18. // slow will be the head of 2nd half
  19. ListNode prev = null, slow = head, fast = head, l1 = head;
  20. while (fast != null && fast.next != null) {
  21. prev = slow;
  22. slow = slow.next;
  23. fast = fast.next.next;
  24. }
  25. prev.next = null;
  26. // step 2. reverse the 2nd half
  27. ListNode l2 = reverse(slow);
  28. // step 3. merge the two halves
  29. merge(l1, l2);
  30. }
  31. ListNode reverse(ListNode head) {
  32. ListNode prev = null, curr = head, next = null;
  33. while (curr != null) {
  34. next = curr.next;
  35. curr.next = prev;
  36. prev = curr;
  37. curr = next;
  38. }
  39. return prev;
  40. }
  41. void merge(ListNode l1, ListNode l2) {
  42. while (l1 != null) {
  43. ListNode n1 = l1.next, n2 = l2.next;
  44. l1.next = l2;
  45. if (n1 == null)
  46. break;
  47. l2.next = n1;
  48. l1 = n1;
  49. l2 = n2;
  50. }
  51. }
  52. }