「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」
重排链表 Reorder List
LeetCode传送门143. 重排链表
题目
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
You are given the head of a singly linked-list. The list can be represented as:
L0 → L1 → … → Ln - 1 → Ln
Reorder the list to be on the following form:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
You may not modify the values in the list's nodes. Only nodes themselves may be changed.
Example:
Input: head = [1,2,3,4]
Output: [1,4,2,3]
Input: head = [1,2,3,4,5]
Output: [1,5,2,4,3]
Constraints:
-
The number of nodes in the list is in the range.
-
1 <= Node.val <= 1000
思考线
解题思路
在本题中,我们要让后一半的内容倒序插入到前面节点中。而单链表中我们又无法实现按下标储存。所以要做这道题的第一个难点就是我们要把链表的节点存起来,以便用的时候能方便的按下标取到。
而在JS中我们肯定要用数组来储存内容是最方便的.
解决完取用的问题后,接下来问题又来了,我们如何能让头部和尾部交替插入呢?
最简单的想法是,我们设两个变量i和j,用来储存开始和结束下标,然后把下标为j的元素插入到i后面,同时把j的下一个元素指向i+1.我们循环遍历,直到不再满足i<j的条件为止。
思路搞定后,我们的代码就很容易实现了,实现内容如下:
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
/**
Do not return anything, modify head in-place instead.
*/
function reorderList(head: ListNode | null): void {
const list = [];
while (head) {
list.push(head);
head = head.next;
}
let i = 0, j = list.length - 1;
while (i < j) {
list[i].next = list[j];
list[j].next = list[i + 1]
i++;
j--;
}
list[i].next = null
};
时间复杂度
O(n): n为链表的长度
这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。