[路飞]_每天刷leetcode_59( 重排链表 Reorder List)

147 阅读2分钟

「这是我参与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,5104] [1, 5 * 10^4].

  • 1 <= Node.val <= 1000


思考线


解题思路

在本题中,我们要让后一半的内容倒序插入到前面节点中。而单链表中我们又无法实现按下标储存。所以要做这道题的第一个难点就是我们要把链表的节点存起来,以便用的时候能方便的按下标取到。

而在JS中我们肯定要用数组来储存内容是最方便的.

解决完取用的问题后,接下来问题又来了,我们如何能让头部和尾部交替插入呢?

最简单的想法是,我们设两个变量ij,用来储存开始和结束下标,然后把下标为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为链表的长度

这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。