当前位置: 首页 > news >正文

(100分)- 单向链表中间节点(Java JS Python)

(100分)- 单向链表中间节点(Java & JS & Python)

题目描述

求单向链表中间的节点值,如果奇数个节点取中间,偶数个取偏右边的那个值。

输入描述

第一行 链表头节点地址 后续输入的节点数n

后续输入每行表示一个节点,格式 节点地址 节点值 下一个节点地址(-1表示空指针)

输入保证链表不会出现环,并且可能存在一些节点不属于链表。

输出描述

单向链表中间的节点值

用例
输入00010 4
00000 3 -1
00010 5 12309
11451 6 00000
12309 7 11451
输出6
说明
输入10000 3
76892 7 12309
12309 5 -1
10000 1 76892
输出7
说明
题目解析

用例1示意图如下

JS本题可以利用数组模拟链表

基于链表数据结构解题

JavaScript算法源码
/* JavaScript Node ACM模式 控制台输入获取 */ const readline = require("readline"); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); const lines = []; let head; let n; rl.on("line", (line) => { lines.push(line); if (lines.length === 1) { [head, n] = lines[0].split(" "); } if (n && lines.length === n - 0 + 1) { lines.shift(); const nodes = {}; lines.forEach((line) => { const [addr, val, nextAddr] = line.split(" "); nodes[addr] = [val, nextAddr]; }); console.log(getResult(head, nodes)); lines.length = 0; } }); function getResult(head, nodes) { const linkedlist = []; let node = nodes[head]; while (node) { const [val, next] = node; linkedlist.push(val); node = nodes[next]; } const len = linkedlist.length; const mid = len % 2 === 0 ? len / 2 : Math.floor(len / 2); return linkedlist[mid]; }
Java算法源码

在Java中,LinkedList的get(index)方法时间复杂度为O(n)而非O(1),这种情况下更推荐使用ArrayList来实现。

import java.util.ArrayList; import java.util.HashMap; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String head = sc.next(); int n = sc.nextInt(); HashMap<String, String[]> nodes = new HashMap<>(); for (int i = 0; i < n; i++) { String addr = sc.next(); String val = sc.next(); String nextAddr = sc.next(); nodes.put(addr, new String[] {val, nextAddr}); } System.out.println(getResult(head, nodes)); } public static String getResult(String head, HashMap<String, String[]> nodes) { // LinkedList<String> link = new LinkedList<>(); ArrayList<String> link = new ArrayList<>(); String[] node = nodes.get(head); while (node != null) { String val = node[0]; String next = node[1]; link.add(val); node = nodes.get(next); } int len = link.size(); int mid = len / 2; return link.get(mid); } }
Python算法源码
# 输入获取 head, n = input().split() nodes = {} for i in range(int(n)): addr, val, nextAddr = input().split() nodes[addr] = [val, nextAddr] # 算法入口 def getResult(head, nodes): linkedlist = [] node = nodes.get(head) while node is not None: val, next = node linkedlist.append(val) node = nodes.get(next) length = len(linkedlist) mid = int(length / 2) return linkedlist[mid] # 算法调用 print(getResult(head, nodes))

链表结构与快慢指针解法

链表作为一种非连续存储的数据结构,本身并不具备真正的索引概念。但在实际应用中,我们经常需要访问特定位置的元素,因此大多数编程语言都为链表提供了"伪索引"功能。以Java的LinkedList为例,虽然提供了get(index)方法,但其底层实现是通过遍历链表节点(逐个访问next属性)来定位目标元素,这意味着每次索引访问都需要O(n)的时间复杂度。

在链表相关问题中,一个常见考点是如何在未知链表长度的情况下找到中间节点。这时,快慢指针算法就派上用场了。

快慢指针的工作原理是:

  • 设置两个指针同时遍历链表
  • 慢指针每次移动1个节点
  • 快指针每次移动2个节点 当快指针到达链表末尾时,慢指针正好位于中间节点位置(对于奇数长度链表取正中间节点,偶数长度则取中间偏右的节点)。

虽然本题给出了节点数量,但这些节点可能属于不同的链表结构,因此实际链表长度仍是未知的。由于题目要求的中间节点定义与快慢指针的结果完全一致,所以采用快慢指针算法是最优解决方案。

Java算法源码
import java.util.HashMap; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String head = sc.next(); int n = sc.nextInt(); HashMap<String, String[]> nodes = new HashMap<>(); for (int i = 0; i < n; i++) { String addr = sc.next(); String val = sc.next(); String nextAddr = sc.next(); nodes.put(addr, new String[] {val, nextAddr}); } System.out.println(getResult(head, nodes)); } public static String getResult(String head, HashMap<String, String[]> nodes) { String[] slow = nodes.get(head); String[] fast = nodes.get(slow[1]); while (fast != null) { slow = nodes.get(slow[1]); fast = nodes.get(fast[1]); if (fast != null) { fast = nodes.get(fast[1]); } else { break; } } return slow[0]; } }
JavaScript算法源码
/* JavaScript Node ACM模式 控制台输入获取 */ const readline = require("readline"); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); const lines = []; let head; let n; rl.on("line", (line) => { lines.push(line); if (lines.length === 1) { [head, n] = lines[0].split(" "); } if (n && lines.length === n - 0 + 1) { lines.shift(); const nodes = {}; lines.forEach((line) => { const [addr, val, nextAddr] = line.split(" "); nodes[addr] = [val, nextAddr]; }); console.log(getResult(head, nodes)); lines.length = 0; } }); function getResult(head, nodes) { let slow = nodes[head]; let fast = nodes[slow[1]]; while (fast) { slow = nodes[slow[1]]; fast = nodes[fast[1]]; if (fast) { fast = nodes[fast[1]]; } else { break; } } return slow[0]; }
Python算法源码
# 输入获取 head, n = input().split() nodes = {} for i in range(int(n)): addr, val, nextAddr = input().split() nodes[addr] = [val, nextAddr] # 算法入口 def getResult(head, nodes): slow = nodes.get(head) fast = nodes.get(slow[1]) while fast is not None: slow = nodes.get(slow[1]) fast = nodes.get(fast[1]) if fast is None: break else: fast = nodes.get(fast[1]) return slow[0] # 算法调用 print(getResult(head, nodes))
http://www.jsqmd.com/news/359084/

相关文章:

  • (100分)- 打印机队列(Java JS Python)
  • 创业三年,记录来时路
  • jwt和oauth2的原理、特点、区别及使用场景
  • 计算机小程序毕设实战-基于springboot+小程序的高校生活互助平台小程序基于SpringBoot的高校报修与互助平台小程序【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 戴尔服务器常用设置
  • 如何在 Teams 中添加一个页面
  • 【课程设计/毕业设计】基于SpringBoot校园生活服务小程序基于springboot+小程序的高校生活互助平台小程序【附源码、数据库、万字文档】
  • STC15F204EA概述
  • 对于tarjan的思考
  • 小程序毕设项目:基于springboot+小程序的高校生活互助平台小程序(源码+文档,讲解、调试运行,定制等)
  • Python快速入门——学习笔记(持续更新中~)
  • 2月8日-(OpenSpec规范)
  • 《深入理解Java虚拟机》| 运行时数据区与OOM异常
  • 小程序计算机毕设之基于springboot+小程序的高校生活互助平台小程序基于SpringBoot校园生活服务小程序(完整前后端代码+说明文档+LW,调试定制等)
  • 【毕业设计】基于springboot+小程序的高校生活互助平台小程序(源码+文档+远程调试,全bao定制等)
  • Kconfig测试
  • 【计算机毕业设计案例】基于springboot+小程序的高校生活互助平台小程序校园互助性小程序的设计与开发(程序+文档+讲解+定制)
  • 《分布式追踪Span-业务标识融合:端到端业务可观测手册》
  • 第一课--环境搭建
  • 《边缘受限设备API客户端轻量化与功能适配实战指南》
  • 别忽视要点!提示工程架构师的提示质量监控告警关键要素
  • CentOS Stream 支持 exFAT 几种方法
  • leetcode 923. 3Sum With Multiplicity 三数之和的多种可能
  • leetcode 困难题 924. Minimize Malware Spread 尽量减少恶意软件的传播
  • leetcode 925. Long Pressed Name 长按键入-耗时100
  • 【无人机控制】模糊神经网络FNN控制器控制固定翼无人机【含Matlab源码 15083期】
  • 【ALA三维路径规划】改进的人工旅鼠算法IALA复杂三维无人机路径规划(含ALA、WOA对比)【含Matlab源码 15085期】
  • Debian挂载飞牛OS创建的RAID分区和Btrfs分区指南
  • AI原生应用领域新趋势:跨语言理解的无限可能
  • ClickHouse在车联网大数据处理中的应用案例