给定一个单链表 L **的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入: head = [1,2,3,4]
输出: [1,4,2,3]
示例 2:
输入: head = [1,2,3,4,5]
输出: [1,5,2,4,3]
题解:
/**
* 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 reorderList = function (head) {
let stack = [], tmp
// 断掉每一条next指针
while (head) {
tmp = head.next;
head.next = null;
stack.push(head);
head = tmp;
}
let i = 0, j = stack.length - 1
while (i < j) {
// 遍历当前值i得next指向对应j位置
stack[i].next = stack[j];
// 当 j != i + 1 j位置next指向i + 1位置
j !== i + 1 && (stack[j].next = stack[i + 1]);
i++;
j--
}
return stack[0]
};
// 方法二:利用栈
var reorderList = function (head) {
const stack = [];
while (head) {
stack.push(head)
head = head.next
}
while (stack.length > 2) {
let h = stack.shift()
let t = stack.pop()
t.next = h.next;
h.next = t
}
stack[stack.length - 1].next = null
return head
}
// 方法三:双指针 翻转插入
var reorderList = function (head) {
if (!head.next) return head;
let slow = head, fast = head.next;
// slow 为第一个结点开始,fast 为第二个结点开始,
// 这样结点总个数奇数或偶数都很好兼容
// fast 走两步,不能一次性走两步,要一步一步走
while (fast && fast.next) {
slow = slow.next;
fast = fast.next
// 对于 fast 第二步,需要先判断,
// 如果 fast 后面还可以再走一步,才往后走
if (fast.next) {
fast = fast.next
}
}
// 链表翻转
let newHead = null, pre = null;
let cur = slow.next;
// 前半部分和后半部分断开联系
slow.next = null;
while (cur) {
pre = cur;
cur = cur.next
pre.next = newHead;
newHead = pre;
}
// 现在 newHead 就是后半段翻转后的样子,然后接下来跟前半部分 依次 插入新链表
let resultHead = new ListNode(0), now = resultHead, flag = true;
slow = head, fast = newHead;
while (slow || fast) {
// 通过 flag 控制现在插入 前半部分 还是 后半部分
if (flag) {
now.next = slow;
slow = slow.next;
} else {
now.next = fast;
fast = fast.next;
}
now = now.next;
flag = !flag;
}
return resultHead.next;
}
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。