本题考察的是快慢指针和一些链表插入删除等操作
题目描述
给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
给定链表 1->2->3->4, 重新排列为 1->4->2->3.
示例 2:
给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.
题目思考
我们首先使用快慢指针找到链表中间的结点,然后把中间结点和他的后驱(.next)断开,形成两个前半截和后半截链表。我们把后半截链表反转,然后把后半截链表的结点依次插入到前半截链表中即可。如下图所示。
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void reorderList(ListNode head) {
if(head==null||head.next==null)
return ;
ListNode res=head;
ListNode fast=head;
ListNode slow=head;
while(fast.next!=null&&fast.next.next!=null){ //使用快慢指针找到中间结点
fast=fast.next.next;
slow=slow.next;
}
ListNode pre=null,cur=slow.next; //截成两个链表
slow.next=null;
while(cur!=null){ //反转第二个链表
ListNode temp=cur.next;
cur.next=pre;
pre=cur;
cur=temp;
}
while(pre!=null){ //将第二个链表的结点依次插入第一个链表
ListNode temp1=res.next;
ListNode temp2=pre.next;
res.next=pre;
pre.next=temp1;
res=temp1;
pre=temp2;
}
}
}