原题链接在这里:https://leetcode.com/problems/reorder-list/
首先想到Method 1是先设置mark=head, 然后每次翻转mark后面的list, 链接mark与反转后新的head, 之后mark = mark.next.直到mark.next == null, Time O(n^2), Space O(1). 这种方法TLE了。
Method 2 先找到中点,断开后反转后半段,在merge两端即可。Time O(n), Space O(1).
Note: 1. 找到中点后,不要忘记断开.
2. 后半段的长度小于等于前半段的长度,所以merge时终止条件是rightHead!=null.
AC Java:
/**
* 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) {
/*
//Method 1
if(head == null || head.next == null || head.next.next == null){
return;
}
ListNode mark = head;
while(mark.next != null){
ListNode cur = mark.next;
ListNode pre;
ListNode tail = mark.next;
ListNode temp;
while(tail.next != null){
pre = cur;
cur = tail.next;
temp = cur.next;
cur.next = pre;
tail.next = temp;
}
mark.next = cur;
mark = mark.next;
}
*/
//Method 2
if(head == null || head.next == null || head.next.next == null){
return;
}
ListNode walker = head;
ListNode runner = head;
while(runner.next != null && runner.next.next != null){
runner = runner.next.next;
walker = walker.next;
}
ListNode rightHead = walker.next;
walker.next = null;
rightHead = reverseList(rightHead);
ListNode mark = head;
while(rightHead != null){
ListNode temp = rightHead.next;
rightHead.next = mark.next;
mark.next = rightHead;
mark = mark.next.next;
rightHead = temp;
}
}
private ListNode reverseList(ListNode head){
ListNode tail = head;
ListNode cur = tail;
ListNode temp;
ListNode pre;
while(tail.next != null){
pre = cur;
cur = tail.next;
temp = cur.next;
cur.next = pre;
tail.next = temp;
}
return cur;
}
}