LeetCode热题(JS版) - 328. 奇偶链表

206 阅读2分钟

题目描述

给定一个单链表,将所有奇数节点放在前面,偶数节点放在后面。要求保持原始相对顺序。

例如: 输入: 1->2->3->4->5->NULL 输出: 1->3->5->2->4->NULL

解法

要解决这个问题,可以使用两个指针 odd 和 even 分别指向奇数节点和偶数节点的位置。然后遍历链表,每次将当前节点添加到对应的奇数或偶数链表的末尾,并分别更新 odd 和 even 指针。

具体实现如下:

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);
  }
}

function oddEvenList(head: ListNode | null): ListNode | null {
  if (!head || !head.next) { // 如果链表为空或只有一个节点,则直接返回原链表
    return head;
  }

  let odd = head; // 奇数位置节点的指针
  let even = head.next; // 偶数位置节点的指针
  const evenHead = even; // 保存偶数位置节点的头部

  while (even && even.next) {
    // 重新连接奇数位置和偶数位置的节点
    odd.next = even.next; // 奇数位置节点的下一个指向当前偶数位置节点的下一个
    odd = odd.next; // 奇数位置指针向后移动至新的奇数位置节点
    even.next = odd.next; // 偶数位置节点的下一个指向当前奇数位置节点的下一个
    even = even.next; // 偶数位置指针向后移动至新的偶数位置节点
  }

  odd.next = evenHead; // 将奇数位置节点的末尾指向偶数位置节点的头部

  return head; // 返回处理后的链表
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是链表的长度。需要遍历整个链表一次。
  • 空间复杂度:O(1)。只需要常数级别的额外空间来存储指针。

总结

本题中,我们使用了两个指针 odd 和 even 分别指向奇数节点和偶数节点的位置,并通过移动指针将节点添加到对应的奇数或偶数链表的末尾。最后将奇数链表的尾部指向偶数链表的头部,完成了节点的重排列。

这种解法时间复杂度为 O(n),空间复杂度为 O(1),非常高效。

如果你有其他的解题思路或优化,请随时分享。