143.题目
Given a singly linked list L: L0?L1?…?Ln-1?Ln,
reorder it to: L0?Ln?L1?Ln-1?L2?Ln-2?…
Example
Given {1,2,3,4}, reorder it to {1,4,2,3}.
第一反应写的代码
class Solution {
public void reorderList(ListNode head) {
if(head == null) return;
if(head.next == null) return;
ListNode pre = head,preLast = head.next;
if(preLast.next == null) return;
while(preLast.next != null){
pre = pre.next;
preLast = pre.next;
}
ListNode next = head.next;
head.next = preLast;
preLast.next = next;
pre.next = null;
reorderList(next);
return;
}
}
总共13组测试用例,跑过了12组,最后一组特别大的显示Time Limit Exceeded
改进……
1.可以找list的中心,从中心分为两个list;
2.对后半部分的实现从后指向前;
3.剩下两个list插空填充就行了。
下面是实现:
public void reorderList(ListNode head) {
if(head == null || head.next == null) return;
///find the middle
ListNode p1 = head;
ListNode p2 = head;
while(p2.next != null && p2.next.next != null){
p1 = p1.next;
p2 = p2.next.next;
}
if(p2.next != null)
p2 = p2.next;
//p1 in the middle of the list
//p2 last in the list
//reverse the latter half of the list 1->2->3->4->5->6 to 1->2->3<-4<-5<-6
ListNode preCurrent = p1;
ListNode current = p1.next;
//if(p1 != head)
p1.next = null;
while(p1 != head && current != null){
ListNode k1 = current.next;
current.next = preCurrent;
preCurrent = current;
current = k1;
}
//merge two list 1->2->3 6->5->4->3
ListNode tmp1 = head;
ListNode tmp2 = p2;
while(tmp1 != tmp2 && tmp1 != null && tmp2 != null){
ListNode k1 = tmp1.next;
ListNode k2 = tmp2.next;
tmp1.next = tmp2;
tmp2.next = k1;
tmp1 = k1;
tmp2 = k2;
}
}