143. Reorder List学习
发布日期:2021-05-17 22:23:12 浏览次数:25 分类:精选文章

本文共 1505 字,大约阅读时间需要 5 分钟。

单向链表的重新排列问题是一个经典的中等难度算法题目。目标是将原链表L0→L1→…→Ln-1→Ln 重新排列为 L0→Ln→L1→Ln-1→L2→Ln-2→…的形式,而不改变节点的值。

问题分析

给定一个单向链表,我们需要将其重新排列,使得前半部分的节点与后半部分的节点交替出现。例如,给定链表{1,2,3,4},重新排列后变为{1,4,2,3}。解决这个问题的关键在于找到链表的中点,并将后半部分反转,然后与前半部分交替连接。

解决思路

  • 找到中点:使用快慢指针法找到链表的中点。快指针每次移动两步,慢指针每次移动一步。当快指针达到末尾时,慢指针位于中点。
  • 分离两部分链表:将链表分为前半部分和后半部分。
  • 反转后半部分:将后半部分链表反转,使其与前半部分交替连接。
  • 代码实现

    public class ReorderList {    public void reorderList(ListNode head) {        if (head == null || head.next == null) {            return;        }        // 找到中点        ListNode fast = head.next;        ListNode slow = head;        while (fast != null && fast.next != null) {            fast = fast.next.next;            slow = slow.next;        }        // 分离两部分        ListNode p = slow.next;        slow.next = null; // 将慢指针作为前半部分的末尾        // 反转后半部分        ListNode pPre = null;        ListNode pSuf = p.next;        while (p != null) {            pSuf = p.next;            p.next = pPre;            pPre = p;            p = pSuf;        }        // 合并两部分        ListNode l1 = head;        ListNode l2 = pPre;        while (l1 != null && l2 != null) {            ListNode nextL1 = l1.next;            ListNode nextL2 = l2.next;            l1.next = l2;            l2.next = nextL1;            l1 = nextL1;            l2 = nextL2;        }    }}

    代码解释

  • 检查特殊情况:如果链表为空或只有一个节点,则直接返回。
  • 快慢指针法:通过快慢指针找到链表的中点。快指针每次移动两步,慢指针每次移动一步。当快指针达到末尾时,慢指针位于中点。
  • 分离链表:将链表分为前半部分和后半部分。
  • 反转后半部分:将后半部分链表反转,使其与前半部分交替连接。
  • 合并链表:将前半部分和反转后的后半部分依次连接,完成重新排列。
  • 这种方法确保了链表的重新排列过程在原地完成,时间复杂度为O(n),空间复杂度为O(1)。

    上一篇:Java多线程看着一篇足够了!
    下一篇:LeetCode学习

    发表评论

    最新留言

    表示我来过!
    [***.240.166.169]2025年05月04日 16时31分50秒