LeetCode 分类刷题:143. 重排链表
题目
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

解析
前置题目:
LeetCode 分类刷题:876. 链表的中间结点
LeetCode 分类刷题:206. 反转链表
思路:
- 找到中间节点
- 反转后半段
- 同时遍历两段进行链接

答案
我的答案:
/*** Definition for singly-linked list.* function ListNode(val, next) {* this.val = (val===undefined ? 0 : val)* this.next = (next===undefined ? null : next)* }*/
/*** @param {ListNode} head* @return {void} Do not return anything, modify head in-place instead.*/
var reverseList = function(head) {let pre = null;let cur = head;while(cur) {nxt = cur.next;cur.next = pre;pre = cur;cur = nxt;}return pre;
}
var reorderList = function(head) {// 找到中间节点let slow = head;let fast = head;while(fast && fast.next) {slow = slow.next;fast = fast.next.next;}// 反转后半段let l2 = reverseList(slow);// 同时遍历两段进行链接let l1 = head;while(l2.next) {const nxt1 = l1.next;const nxt2 = l2.next;l1.next = l2;l2.next = nxt1;l1 = nxt1;l2 = nxt2;}
};
灵神答案:
// 876. 链表的中间结点
function middleNode(head) {let slow = head, fast = head;while (fast !== null && fast.next !== null) {slow = slow.next;fast = fast.next.next;}return slow;
}// 206. 反转链表
function reverseList(head) {let pre = null, cur = head;while (cur !== null) {const nxt = cur.next;cur.next = pre;pre = cur;cur = nxt;}return pre;
}var reorderList = function(head) {const mid = middleNode(head);let head2 = reverseList(mid);while (head2.next !== null) {const nxt = head.next;const nxt2 = head2.next;head.next = head2;head2.next = nxt;head = nxt;head2 = nxt2;}
};// 作者:灵茶山艾府
// 链接:https://leetcode.cn/problems/reorder-list/solutions/1999276/mei-xiang-ming-bai-yi-ge-shi-pin-jiang-t-u66q/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析
时间复杂度:O(n),其中 n 为链表的长度。
空间复杂度:O(1),仅用到若干额外变量。
