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}
.
思路:
(1 )用快慢指针找到中间节点
(2) 翻转中间节点之后的链表
(3) 断开前半段(即找到中间节点并保存了中间节点所指向的节点之后,将中间节点的指针设为NULL)
和翻转后的后半段元素
(4) 把前半段和翻转后的后半段元素以交叉的方式合并起来(如果重新创建一个链表穿插存储前后半段,时间 会超时。所以要善于运用链表的merge)
/**
* 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) {
if (head == null) {
return ;
}
//存储新的链表
ListNode dummy = new ListNode(0);
ListNode headA =head;
dummy.next = headA;
ListNode fast = head;
ListNode slow = head;
//找到中间节点
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
ListNode sNext = slow.next;
//链表A;
slow.next = null;
//反转中间节点之后的链表B
ListNode headB = reverseNode(sNext);
while (headA != null && headB != null) {
ListNode tmpNode = headA.next;
headA.next = headB;
headB = headB.next;
headA.next.next = tmpNode;
headA = tmpNode;
}
}
public ListNode reverseNode(ListNode head) {
if (head == null) {
return head;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode curNode = head.next;
head.next = null;
while (curNode != null) {
ListNode next = curNode.next;
curNode.next = dummy.next;
dummy.next = curNode;
curNode = next;
}
return dummy.next;
}
}
感想:可以看出翻转链表非常重要,是做很多题目的基础。还有merge的思想也很重要