问题:
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个结点后,以此类推……
如:1 --> 2 --> 3 -- > 4 --> 5 --> 6 转换为 1 --> 6 --> 2 --> 5 --> 3 --> 4
① 先用快慢指针找到链表的中点,然后翻转链表后半部分,再和前半部分组合。需要注意的是把链表分成两半时,前半段的尾节点要置为NULL,翻转链表时也要把尾节点置为NULL。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution { //2ms
public void reorderList(ListNode head) {
if (head == null || head.next == null) {
return;
}
//把整个链表划分成两个等长的子链表,如果原链表长度为奇数,那么第一个子链表的长度多1.
ListNode slow = head;
ListNode fast = head;
while(fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
ListNode head1 = head;
ListNode head2 = slow.next;
slow.next = null;
//翻转第二个子链表
ListNode cur = head2;
ListNode post = cur.next;
cur.next = null;
while(post != null){
ListNode tmp = post.next;
post.next = cur;
cur = post;
post = tmp;
}
head2 = cur;
//将两个子链表合并
ListNode p1 = head1;
ListNode p2 = head2;
while(p2 != null){
ListNode tmp1 = p1.next;
ListNode tmp2 = p2.next;
p1.next = p2;
p2.next = tmp1;
p1 = tmp1;
p2 = tmp2;
}
}
}