重排链表
题目描述
将给定的单链表 L\ L L: L0→L1→…→Ln−1→LnL_0→L_1→…→L_{n-1}→L_ nL0→L1→…→Ln−1→Ln
重新排序为:L0→Ln→L1→Ln−1→L2→Ln−2→…L_0→L_n →L_1→L_{n-1}→L_2→L_{n-2}→…L0→Ln→L1→Ln−1→L2→Ln−2→…
要求使用原地算法,不能改变节点内部的值,需要对实际的节点进行交换。
例如:
对于给定的单链表{10,20,30,40},将其重新排序为{10,40,20,30}.
代码
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public void reorderList(ListNode head) {
if(head == null || head.next == null || head.next.next == null)
return ;
//快慢指针,找到中间节点
ListNode fast = head;
ListNode slow = head;
while(fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
}
ListNode mid = slow;
ListNode start = head;
ListNode end = mid.next;
//断链,分成两半
mid.next = null;
//翻转end链条
ListNode pre = end;
ListNode cur = end.next;
pre.next = null;
while(cur != null){
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
end = pre;
while(start != null && end!=null){
ListNode next1 = start.next;
ListNode next2 = end.next;
start.next = end;
end.next = next1;
start = next1;
end = next2;
}
return;
}
}