链接:https://www.nowcoder.com/questionTerminal/3d281dc0b3704347846a110bf561ef6b?f=discussion
来源:牛客网
import java.util.List;
import java.util.Stack;
/*
将给定的单链表L: L 0→L 1→…→L n-1→L n,
重新排序为: L 0→L n →L 1→L n-1→L 2→L n-2→…
要求使用原地算法,并且不改变节点的值
例如:
对于给定的单链表{1,2,3,4},将其重新排序为{1,4,2,3}.
*/
public class Solution {
public void reorderList(ListNode head) {
if (head == null || head.next == null)
return;
// 快慢指针找到中间节点
ListNode fast = head;
ListNode slow = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
//拆分链表,并反转中间节点之后的链表
ListNode curNode = slow.next; //定义一个辅助curNode
slow.next = null; //将原来的链表拆分,拆分后的最后一个非空节点为slow
ListNode preNode = null; //定义一个空的preNode,表示curNode之前的节点
while (curNode != null) {
ListNode nextNode = curNode.next; //
curNode.next = preNode; //当前节点的下一个节点指向前面的节点,即指针反转
preNode = curNode; //preNode后移到curNode上
curNode = nextNode; //curNode后移
}
//执行完反转操作之后,反转链表的第一个节点为preNode
//合并两个链表
ListNode first = head; //first指向第一个链表的头结点
ListNode after = preNode; //after指向第二个反转后的链表的头结点
while (first != null && after != null) {
ListNode firstTemp = first.next;
ListNode afterTemp = after.next;
first.next = after; //将after的第一个数放在first后面
first = firstTemp; //first后移到firstTemp
after.next = first; //after指向新的first
after = afterTemp; //after后移到afterTemp
}
}
}