1 public ListNode reorder(ListNode head) { 2 // Write your solution here 3 if (head == null || head.next == null) { 4 return head; 5 } 6 ListNode mid = findMid(head); 7 ListNode secHead = reverse(mid.next); 8 merge(head, secHead); 9 return head; 10 } 11 12 private ListNode findMid(ListNode head) { 13 ListNode fast = head, slow = head; 14 while (fast.next != null && fast.next.next != null) { 15 fast = fast.next.next; 16 slow = slow.next; 17 } 18 return slow; 19 } 20 21 private ListNode reverse(ListNode head) { 22 ListNode prev = null, curr = head, next = null; 23 while (curr != null) { 24 next = curr.next; 25 curr.next = prev; 26 prev = curr; 27 curr = next; 28 } 29 return prev; 30 } 31 32 private void merge(ListNode p1, ListNode p2) { 33 ListNode temp1 = null, temp2 = null; 34 while (p2.next != null) { 35 temp1 = p1.next; 36 temp2 = p2.next; 37 p1.next = p2; 38 p2.next = temp1; 39 p1 = temp1; 40 p2 = temp2; 41 } 42 if (p1.next != null) { 43 temp1 = p1.next; 44 p1.next = p2; 45 p2.next = temp1; 46 temp1.next = null; 47 } else { 48 p1.next = p2; 49 p2.next = null; 50 } 51 }
注意点:
1. sanity test 的时候需要判断 if (head == null || head.next == null) {} 后面半句话的判断是为了在第三部分merge的时候不会出现NPE.
2. merge() 的部分, 思路是用两个temp 指针来进行 .next位的预存. 而需要注意的是 while (p2.next != null) 这一步很重要, 相当于把结尾部分的判断做post processing. 之后再判断 if (p1.next != null).