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}
.
在ctci的链表那节有个类似的题。这里这道题要多一步反转链表而已。
1.把链表从中间分成前后两部分。如果链表长度是奇数,那么前面的链表长度多一。
2.把后半部分链表反转
3.再把两个链表合并
没有用到extra space,时间复杂度O(n)
public class Solution {
public void reorderList(ListNode head) {
if(head == null)
return;
//divide the list into two lists
ListNode fast = head;
ListNode slow = head;
while(fast.next != null){
fast = fast.next;
if(fast.next != null){
fast = fast.next;
}
else{
break;
}
slow = slow.next;
}
//reverse the second part
ListNode secondHead = reverseList(slow.next);
slow.next = null;
//merge the two lists
merge(head, secondHead);
}
public ListNode reverseList(ListNode node){
ListNode p = node;
if(p == null || p.next == null)
return p;
ListNode q = p.next;
p.next = null;
while(q != null){
ListNode r = q.next;
q.next = p;
p = q;
q = r;
}
return p;
}
public void merge(ListNode node1, ListNode node2){
ListNode p = node1;
ListNode q = node2;
while( p != null && q != null){
ListNode r = p.next;
ListNode m = q.next;
p.next = q;
q.next = r;
p = r;
q = m;
}
}
}