Java关于重排链表详细解析

yizhihongxing

Java关于重排链表详细解析

问题描述

给定一个单链表 L 的头节点 head ,单链表 L 表示为:

L0 -> L1 -> L2 -> ... -> Ln-1 -> Ln

需要将单链表 L 进行重新排列,使得新的链表既符合以下格式,也保留原链表元素的相对顺序:

L0 -> Ln -> L1 -> Ln-1 -> L2 -> Ln-2 -> ...

例如,将单链表 L = 1 -> 2 -> 3 -> 4 -> 5 -> 6 进行重排后,新链表应为 1 -> 6 -> 2 -> 5 -> 3 -> 4 。

解题思路

初步看到这道题目,我们很容易想到的是:将单链表拆成前半段与后半段,然后将后半段翻转,最后将前半段与后半段交叉拼接。

将单链表拆成前半段与后半段

首先,我们需要找到单链表 L 的中间节点,可以使用快慢指针的方法,一个指针每次向后移动 1 个节点,另一个指针每次向后移动 2 个节点,当快指针到达链表末尾时,慢指针恰好到达中间位置,这样便可以将单链表拆分成前半段与后半段。

int length = 0;
ListNode node = head;
while (node != null) {
    length++;
    node = node.next;
}

ListNode node1 = head;
ListNode node2 = null;

for (int i = 0; i < (length + 1) / 2; i++) {
    node2 = node1;
    node1 = node1.next;
}

node2.next = null; // 将链表断成两半

翻转后半段链表

接下来,我们需要对后半段链表进行翻转。这个问题不难,只需要使用三个指针,分别指向当前节点、前驱节点和后继节点,然后对当前节点的 next 指针进行反转即可。

/**
 * 翻转链表
 * @param head
 */
public void reverseList(ListNode head) {
    ListNode pre = null;
    ListNode cur = head;
    ListNode next = null;

    while (cur != null) {
        next = cur.next;
        cur.next = pre;
        pre = cur;
        cur = next;
    }
}

交叉拼接前半和后半段链表

最后,我们将前半段与翻转后的后半段依次交叉拼接即可。

ListNode cur1 = head;
ListNode cur2 = newHead;
ListNode next1 = null;
ListNode next2 = null;

while (cur2 != null) {
    next1 = cur1.next;
    next2 = cur2.next;

    cur1.next = cur2;
    cur2.next = next1;

    cur1 = next1;
    cur2 = next2;
}

完整代码:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        if (head == null || head.next == null) {
            return;
        }

        // 将链表断成两半
        int length = 0;
        ListNode node = head;
        while (node != null) {
            length++;
            node = node.next;
        }

        ListNode node1 = head;
        ListNode node2 = null;

        for (int i = 0; i < (length + 1) / 2; i++) {
            node2 = node1;
            node1 = node1.next;
        }

        node2.next = null;

        // 翻转链表
        ListNode pre = null;
        ListNode cur = node1;
        ListNode next = null;

        while (cur != null) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }

        ListNode newHead = pre;

        // 交叉拼接前半和后半段链表
        ListNode cur1 = head;
        ListNode cur2 = newHead;
        ListNode next1 = null;
        ListNode next2 = null;

        while (cur2 != null) {
            next1 = cur1.next;
            next2 = cur2.next;

            cur1.next = cur2;
            cur2.next = next1;

            cur1 = next1;
            cur2 = next2;
        }
    }
}

示例说明

示例 1

单链表 L = 1 -> 2 -> 3 -> 4 -> 5 -> 6

中间节点为 3 ,将单链表拆分成前半段 1 -> 2 -> 3 和后半段 4 -> 5 -> 6

翻转后半段链表,得到 6 -> 5 -> 4

交叉拼接前半段和后半段链表,得到 1 -> 6 -> 2 -> 5 -> 3 -> 4

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java关于重排链表详细解析 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 细说集群技术(cluster)

    细说集群技术(cluster) 集群技术是一种将多个计算机联合起来协同工作的方式,以实现提高系统性能、提高可靠性、实现负载均衡等目标。在大型网站、云计算、大数据等领域中广泛应用。本文将介绍集群技术的基本概念、应用场景、以及实现方式。 集群技术的基本概念 集群技术是一种将多个计算机联合起来协同工作的方式。通过将多台计算机组合成一个更大的逻辑系统,从而达到分布式…

    其他 2023年3月28日
    00
  • htmlhelpworkshop创作、调用方法和技巧

    以下是关于HTML Help Workshop的完整攻略: HTML Help Workshop简介 HTML Help Workshop是一个用于创建Windows帮助文件的免费工具,它可以将HTML文件转换为CHM格式的帮助文件。HTML Help Workshop提供了一个易于使用的界面和多种功能,包括目录、索引、搜索等。 创作帮助文件 以下是使用HT…

    other 2023年5月6日
    00
  • json解析—gson以及gsonformat插件的运用

    json解析—gson以及gsonformat插件的运用 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript语言的子集,可以被各种编程语言读取和写入。相对于XML格式,JSON更为简洁,易于阅读和编写。 GSON简介 GSON是Google提供的用于Java和Android的…

    其他 2023年3月29日
    00
  • you-get 多网站视频下载工具 非常方便

    you-get 多网站视频下载工具 非常方便 作为一个视频爱好者,相信不少人遇到过在各大视频网站看到喜欢的视频,却找不到下载链接或者需要下载特定格式的视频而苦恼。此时,我们可以使用一款叫做you-get的开源工具来避免这些问题。 you-get是一个类似wget的命令行下载器,但是它专门用于下载多种网站上的视频内容,包括但不限于YouTube、Bilibil…

    其他 2023年3月28日
    00
  • mysql时间与字符串之间相互转换

    以下是详细讲解“MySQL时间与字符串之间相互转换的完整攻略”的标准Markdown格式文本: MySQL时间与字符串之间相互转换的完整攻略 在MySQL中,时间和字符串之间的相互转换是常见的操作。本攻略将介绍如何在MySQL中进行时间和字符串之间相互转换。 时间转换为字符串 使用DATE_FORMAT函数可以将时间转换为字符串。DATE_FORMAT函数的…

    other 2023年5月10日
    00
  • c语言链表基本操作(带有创建链表 删除 打印 插入)

    C语言链表基本操作 概述 链表是一种常见的数据结构,它由若干个节点组成,并且每个节点都包含一个指向下一个节点的指针。链表可以动态地进行创建、删除、插入等操作。本文将介绍C语言链表的基本操作,包括创建链表、删除节点、打印链表以及插入节点。 创建链表 链表的创建通过在堆上动态分配空间来实现。下面是一个简单的节点结构体定义: typedef struct Node…

    other 2023年6月27日
    00
  • Atitit 桌面软件跨平台gui解决方案 javafx webview

    Atitit 桌面软件跨平台GUI解决方案:JavaFX WebView的完整攻略 Atitit是一款跨平台的桌面软件,它使用JavaFX WebView作为GUI解决方案。本攻略将介绍如何使用JavaFX WebView创建GUI,并提供两个示例说明。 步骤一:安装JavaFX 首先,我们需要安装JavaFX。可以通过以下方式安装: 访问JavaFX官网(…

    other 2023年5月6日
    00
  • fastDFS文件服务器迁移

    FastDFS文件服务器迁移 FastDFS是一个开源的分布式文件系统,具有高性能、高可靠性、易部署、易扩展等特点,被广泛应用于大规模文件存储场景。但是,在实际使用过程中,我们难免会遇到需要迁移FastDFS文件服务器的情况,本文将介绍FastDFS文件服务器迁移的相关操作和注意事项。 迁移前准备工作 在进行FastDFS文件服务器的迁移之前,我们需要进行以…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部