Link: https://leetcode.com/problems/reorder-list/
Idea
- Find the middle point of the list and divide the list into two parts by setting mid.next = null;
- reverse the second half
- Merge two list by retrieving one node from each list at a time
Code
public class Solution {
public void reorderList(ListNode head) {
if (head == null || head.next == null) {
return;
}
ListNode mid = findMid(head);
ListNode p1 = head;
ListNode p2 = reverse(mid.next);
mid.next = null;
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
while (p1 != null && p2 != null) {
tail.next = p1;
p1 = p1.next;
tail = tail.next;
tail.next = p2;
p2 = p2.next;
tail = tail.next;
}
if (p1 != null) {
tail.next = p1;
}
head = dummy.next;
}
private ListNode findMid(ListNode head) {
if (head == null) {
return null;
}
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
private ListNode reverse(ListNode head) {
if (head.next == null) {
return head;
}
ListNode newHead = reverse(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}