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}.
Let’s give the code directly.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public void reorderList(ListNode head) {
if (head == null || head.next == null) return;
// Find the middle of the list
ListNode p1 = head;
ListNode p2 = head;
while (p2.next != null && p2.next.next != null) {
p1 = p1.next;
p2 = p2.next.next;
}
// Reverse the half after middle
ListNode preMiddle = p1;
ListNode preCurrent = p1.next;
while (preCurrent.next != null) {
ListNode current = preCurrent.next;
preCurrent.next = current.next;
current.next = preMiddle.next;
preMiddle.next = current;
}
// Start reorder one by one.
p1 = head;
p2 = preMiddle.next;
while (p1 != preMiddle) {
preMiddle.next = p2.next;
p2.next = p1.next;
p1.next = p2;
p1 = p2.next;
p2 = preMiddle.next;
}
}
}
Let’s see some Python Code.
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reorderList(self, head):
if not head:
return
# find the mid point
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# reverse the second half in-place
pre, node = None, slow
while node:
pre, node.next, node = node, pre, node.next
# Merge in-place; Note : the last node of "first" and "second" are the same
first, second = head, pre
while second.next:
first.next, first = second, first.next
second.next, second = first, second.next
return
Just the same idea!
Reference!
[1] All solution
[2] Python solution
[3] Java solution