[题目链接](剑指 Offer II 026. 重排链表 - 力扣(LeetCode) (leetcode-cn.com))
思路
- 可以分成三个部分,1.将整个链表从中间进行分割成两个链表 2.将后半段链表进行翻转 3.将两段链表进行拼接
- 当链表节点数为奇数时,前半段链表会多出一个节点
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseNode(ListNode head) {//返回反转链表 //也会将原来的链表进行翻转
ListNode pre = null;
ListNode node = head;
while(node != null) {
ListNode next = node.next;
node.next = pre;
pre = node;
node = next;
}
return pre;
}
private void link(ListNode node1, ListNode node2, ListNode head){//将分割的两段链表进行拼接
ListNode pre = head;
while(node1 != null && node2 != null) {
ListNode next = node1.next;
pre.next = node1;
node1.next = node2;
pre = node2;
node2 = node2.next;
node1 = next;
}
if(node1 != null) pre.next = node1; //如果链表的节点数是奇数个,那么第一段链表会多一个节点
}
public void reorderList(ListNode head) { //使用快慢双指针将链表从中间分割开
ListNode dummy = new ListNode(0);
dummy.next = head; //哨兵节点
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next;
if(fast.next != null) fast = fast.next;
}
ListNode second = slow.next;
slow.next = null;
link(head,reverseNode(second),dummy);
}
}