一.问题描述
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
思路 :
1.寻找链表的中间节点
2.反转中后部分节点
3.合并前后部分节点
注意找到中间节点后,需要将找到的mid节点的next节点置为null,不然会形成环。
合并两个链表图解
二.示例代码
public class RearrangeNode {
public static void main(String[] args) {
ListNode listNode = new ListNode(1);
ListNode listNode2 = new ListNode(2);
ListNode listNode3 = new ListNode(3);
ListNode listNode4 = new ListNode(4);
ListNode listNode5 = new ListNode(5);
listNode.next = listNode2;
listNode2.next = listNode3;
listNode3.next = listNode4;
listNode4.next = listNode5;
rearrangeNode(listNode);
System.out.println(listNode);
}
/**
* 1.寻找链表的中间节点
* 2.反转中后部分节点
* 3.合并前后部分节点
*
* @param head
* @return
*/
private static void rearrangeNode(ListNode head) {
if (head == null || head.next == null) {
return;
}
ListNode midNode = findMidNode(head);
ListNode reverseNode = midNode.next;
midNode.next = null;
reverseNode = reverseNode(reverseNode);
mergeNode(head, reverseNode);
}
private static void mergeNode(ListNode l1, ListNode l2) {
ListNode l1_tmp, l2_tmp;
while (l1 != null && l2 != null) {
l1_tmp = l1.next;
l2_tmp = l2.next;
l1.next = l2;
l1 = l1_tmp;
l2.next = l1;
l2 = l2_tmp;
}
}
private static ListNode reverseNode(ListNode midNode) {
ListNode pre = null;
ListNode cur = midNode;
while (cur != null) {
ListNode newNode = cur.next;
cur.next = pre;
pre = cur;
cur = newNode;
}
return pre;
}
private static ListNode findMidNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
}