* 将给定的单链表\ L L: L_0→L_1→…→L_{n-1}→L_ nL
* 0
* <p>
* →L
* 1
* <p>
* →…→L
* n−1
* <p>
* →L
* n
*
* <p>
* 重新排序为:L_0→L_n →L_1→L_{n-1}→L_2→L_{n-2}→…L
* 要求使用原地算法,不能只改变节点内部的值,需要对实际的节点进行交换。
* <p>
* 数据范围:链表长度 0 \le n \le 200000≤n≤20000 ,链表中每个节点的值满足 0 \le val \le 10000≤val≤1000
* <p>
*/
public class A068_reorderList {
public static void reorderList(ListNode head) {
if (head == null || head.next == null || head.next.next == null) {
return;
}
//找中点,链表分成两个
ListNode slow = head;
ListNode fast = head;
//快慢指针,把整个链表分开成两部分
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode newHead = slow.next;
//要断开后面的
slow.next = null;
//第二个链表倒置,反转后半部分链表
newHead = reverseList(newHead);
//链表节点依次连接
while (newHead != null) {
//先把后半部分逆序的链表下个节点保存为临时节点
ListNode temp = newHead.next;
//把下个节点的next指向头结点的下一个节点
newHead.next = head.next;
//头结点的下一个指向新的节点
head.next = newHead;
//头节点重新赋值(此时的newHead.next已经是指向)
head = newHead.next;
//把临时保存的节点赋值给新的节点
newHead = temp;
}
}
/**
* 链表进行反转
*
* @param head
* @return
*/
private static ListNode reverseList(ListNode head) {
if (head == null) {
return null;
}
ListNode curr = head;
ListNode prev = null;
while (curr != null) {
ListNode temp = curr.next;
curr.next = prev;
prev = curr;
curr = temp;
}
return prev;
}
}
链表交替排列
最新推荐文章于 2025-11-24 13:17:15 发布
本文介绍如何使用原地算法重排单链表,通过快慢指针找到中点,将链表分为两部分,然后反转后半部分并逐步连接。适合0到200000长度链表,值域0到1000。
833

被折叠的 条评论
为什么被折叠?



