面试算法26:重排链表

news/2025/1/15 21:33:26/

问题

给定一个链表,链表中节点的顺序是L0→L1→L2→…→Ln-1→Ln,请问如何重排链表使节点的顺序变成L0→Ln→L1→Ln-1→L2→Ln-2→…?
在这里插入图片描述

分析

首先把链表分成前后两半。在示例链表中,前半段链表包含1、2、3这3个节点,后半段链表包含4、5、6这3个节点。然后把后半段链表反转。示例链表的后半段链表反转之后,节点的顺序变成6、5、4。最后从前半段链表和后半段链表的头节点开始,逐个把它们的节点连接起来形成一个新的链表。先把前半段链表和后半段链表的头节点1和6连接起来,再把处在第2个位置的节点2和5连接起来,最后把两个尾节点3和4连接起来,因此在新的链表中节点的顺序是1、6、2、5、3、4。

可以使用双节点来寻找链表的中间节点。如果一快一慢两个指针同时从链表的头节点出发,快的指针一次顺着next指针向前走两步,而慢的指针一次只走一步,那么当快的指针走到链表的尾节点时慢的指针刚好走到链表的中间节点。

一个值得注意的问题是,链表的节点总数既可能是奇数也可能是偶数。当链表的节点总数是奇数时,就要确保链表的前半段比后半段多一个节点。

public class Test {public static void main(String[] args) {ListNode listNode1 = new ListNode(1);ListNode listNode2 = new ListNode(2);ListNode listNode3 = new ListNode(3);ListNode listNode4 = new ListNode(4);ListNode listNode5 = new ListNode(5);ListNode listNode6 = new ListNode(6);ListNode listNode7 = new ListNode(7);ListNode listNode8 = new ListNode(8);ListNode listNode9 = new ListNode(9);listNode1.next = listNode2;listNode2.next = listNode3;listNode3.next = listNode4;listNode4.next = listNode5;listNode5.next = listNode6;reorderList(listNode1);while (listNode1 != null) {System.out.println(listNode1.val);listNode1 = listNode1.next;}}public static void reorderList(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode fast = dummy;ListNode slow = dummy;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next;if (fast.next != null) {fast = fast.next;}}ListNode temp = slow.next;slow.next = null;link(head, reverseList(temp), dummy);}private static void link(ListNode node1, ListNode node2, ListNode head) {ListNode prev = head;while (node1 != null && node2 != null) {ListNode temp = node1.next;prev.next = node1;node1.next = node2;prev = node2;node1 = temp;node2 = node2.next;}if (node1 != null) {prev.next = node1;}}public static ListNode reverseList(ListNode head) {ListNode prev = null;ListNode cur = head;while (cur != null) {ListNode next = cur.next;cur.next = prev;prev = cur;cur = next;}return prev;}
}

http://www.ppmy.cn/news/1160392.html

相关文章

pdf转二维码怎么做?pdf二维码制作简单技巧

pdf是一种很常见的文件储存格式,一般通知、发票、简历都会保存为这种格式来使用,那么需要将pdf格式文件做成二维码,该用什么方式来制作呢?下面给大家分享一个pdf转二维码的在线工具,可以通过上传文件一键生成二维码&am…

目标检测YOLO实战应用案例100讲-基于YOLOv5的船舶检测

目录 前言 国内外研究现状 目标检测研究现状 船舶检测研究领域现状

【Java 进阶篇】JavaScript DOM Document对象详解

在前端开发中,DOM(文档对象模型)扮演着重要的角色。它允许我们使用JavaScript来与网页文档进行交互,实现动态的网页效果。DOM的核心部分之一就是Document对象,它代表了整个HTML文档。在本篇博客中,我们将深…

UWB和RFID结合使用-最大限度地提高资产跟踪效率

随着未来工厂和工业 4.0 创新部署在全球范围内蓬勃发展,实时定位系统 RTLS越来越被认为是制造过程中最具生产力、成本效益、影响力和破坏性最小的附加系统之一。 考虑到这一点,许多公司现在面临着决定哪种 RTLS 技术最适合他们的需求。有多种 RTLS 解决…

axios 请求的缓存封装

前言 咱们的网站或者程序,每一个页面和操作都需要请求后端接口来获取响应和渲染页面,抛开post请求方式的接口不说,部分get请求得到的数据,短时间内不会更新,或者短时间得到的响应数据不会变化,这个时候就可…

什么是高阶成分(HOC)

高阶组件(Higher-Order Component,HOC)是一种在React中用于组件复用和逻辑抽象的设计模式。它本质上是一个函数,接受一个组件作为参数,并返回一个新的组件。 1. HOC的作用: HOC允许我们在不修改原始组件的…

ChatGPT技术或加剧钓鱼邮件攻击

我们对ChatGPT这一新技术并不陌生,也早就听闻ChatGPT可以通过某种方式绕过安全机制,对目标进行入侵。 ChatGPT的“越狱”技术已经迭代数次,甚至有了先进的“邪恶GPT”WormGPT和FraudGPT,两者都能快速实现钓鱼邮件骗局。 安全分析…

[架构之路-240]:目标系统 - 纵向分层 - 应用层 - 应用层协议与业务应用程序的多样化,与大自然生物的丰富多彩,异曲同工

目录 前言: - 倒金子塔结构 - 大自然的组成 一、应用层在计算机系统中的位置 1.1 计算机应用程序的位置 1.1.1 业务应用程序概述 1.1.2 应用程序的分类 - 按照计算机作用范围 1.1.3 业务应用程序分类 - 按照行业分类 1.2 网络应用协议的位置 1.2.1 网络协…