LeetCode 3110 · Score of a String 字符串得分:单次遍历求相邻字符 ASCII 差绝对值之和(附 9+ 语言实现)
发布时间:2026/9/18 23:00:32 锦皓数字建站
`)
LeetCode 3110 · Score of a String 字符串得分单次遍历求相邻字符 ASCII 差绝对值之和附 9 语言实现【免费下载链接】leetcodeLeetcode solutions项目地址: https://gitcode.com/GitHub_Trending/leetcode1/leetcode本文基于 NeetCode 题解仓库中的 score-of-a-string.md 展开系统讲解 LeetCode 3110「Score of a String字符串得分」的定义、求解思路与多语言实现将字符串中每一对相邻字符的 ASCII 码差值取绝对值后累加。读完你将掌握这种单次遍历 相邻元素处理的基础字符串模式理解ord/charAt/charCodeAt/asciiValue等各语言取字符码值的 API并能在 Python、Java、C、JavaScript、C#、Go、Kotlin、Swift、Rust 等语言中写出无边界错误、无遗漏绝对值的正确实现。问题定义什么是字符串得分给定一个字符串s其得分定义为所有相邻字符 ASCII 值之差的绝对值之和score(s) Σ |ascii(s[i]) - ascii(s[i1])|, i 0 .. n - 2其中n为字符串长度。长度为n的字符串恰好存在n - 1对相邻字符因此得分是这n - 1个非负差值之和。通过两个例子可以直观验证读者可自行用任意语言的取码函数复核输入字符 ASCII 序列相邻差绝对值得分helloh104, e101, l108, l108, o1113 7 0 313zazz122, a97, z12225 2550abca97, b98, c991 12aaa97, a9700前置知识Prerequisites原文档在进入算法前列出了三个必须具备的基础概念这里逐一补充其在本问题中的具体含义字符串遍历String iteration——使用下标i逐个访问字符串中的字符。本题需要在遍历的同时访问s[i]与s[i 1]因此必须对当前下标 下一个下标的配对方式有清晰认识。ASCII 值ASCII values——ASCII 将字符映射为 0127 的整数。本题中A对应 65a对应 970对应 48小写字母az连续覆盖 97122。字符参与算术运算时各语言会自动或需要显式将其转换为整数码值。绝对值Absolute value——由于相邻两个字符的大小顺序不定可能是s[i] s[i1]差值可能为负必须用abs()取绝对值保证每个差值都以非负形式累加。各语言获取字符码值的核心 API 对比如下这也是下文多语言实现的关键差异点语言取码方式说明Pythonord(s[i])显式调用内建函数Java / C#s.charAt(i)/s[i]char参与算术运算自动提升为intCs[i]char直接相减结果提升为intJavaScripts.charCodeAt(i)返回 Unicode 码点Goint(s[i])索引得到byte需显式转换为int再相减Kotlins[i].codeChar.code扩展属性Swiftchars[i].asciiValue!返回UInt8?需解包Rustbytes[i] as i32先取字节再转有符号整数算法思路Intuition原文档给出的核心直觉非常简洁既然要比较每个字符与其邻居只需完整遍历一次字符串每走到位置i就计算s[i]与s[i 1]的 ASCII 差值取绝对值后累加到结果变量res。整个过程不需要任何额外数据结构也不需要预排序或预处理——问题的结构决定了它就是一次朴素的线性扫描。算法步骤Algorithm原文档将算法归纳为三步初始化一个变量res用于保存累加结果初值为 0。从下标0遍历到n - 2含对每个位置i计算|ascii(s[i]) - ascii(s[i 1])|将该差值加到res上。返回res作为最终答案。这里有一个值得强调的细节循环上界是n - 2而非n - 1。因为当i n - 2时访问的已经是最后一对(s[n-2], s[n-1])处理完这对后所有相邻关系都已覆盖。多语言实现继承原文档全部代码以下 9 种语言的实现完整继承自原文档每段代码都保持O(n)时间、O(1)空间的复杂度Pythonclass Solution: def scoreOfString(self, s: str) - int: res 0 for i in range(len(s) - 1): res abs(ord(s[i]) - ord(s[i 1])) return resord()将单个字符转为 Unicode 码点本题输入均为 ASCII 字符等价于 ASCII 值range(len(s) - 1)恰好生成0 .. n-2不会越界。Javapublic class Solution { public int scoreOfString(String s) { int res 0; for (int i 0; i s.length() - 1; i) { res Math.abs(s.charAt(i) - s.charAt(i 1)); } return res; } }charAt返回char相减时自动提升为intMath.abs作用于两个int的差。Cclass Solution { public: int scoreOfString(string s) { int res 0; for (int i 0; i s.length() - 1; i) { res abs(s[i] - s[i 1]); } return res; } };C 中std::abs对int重载char相减先提升为int逻辑与 Java 一致。JavaScriptclass Solution { /** * param {string} s * return {number} */ scoreOfString(s) { let res 0; for (let i 0; i s.length - 1; i) { res Math.abs(s.charCodeAt(i) - s.charCodeAt(i 1)); } return res; } }JavaScript 字符串不能按下标直接得到码值必须通过charCodeAt(i)取字符的 Unicode 码点。C#public class Solution { public int ScoreOfString(string s) { int res 0; for (int i 0; i s.Length - 1; i) { res Math.Abs(s[i] - s[i 1]); } return res; } }C# 的string索引器返回char与 Java 类似会自动提升为int参与减法。Gofunc scoreOfString(s string) int { res : 0 for i : 0; i len(s)-1; i { diff : int(s[i]) - int(s[i1]) if diff 0 { diff -diff } res diff } return res }Go 的math包只提供浮点类型的Abs对int需要手动判断符号——原文档的这一写法正是利用了负数取反即绝对值的性质避免引入额外的类型转换开销。Kotlinclass Solution { fun scoreOfString(s: String): Int { var res 0 for (i in 0 until s.length - 1) { res kotlin.math.abs(s[i].code - s[i 1].code) } return res } }Char.code是 Kotlin 中获取字符码值的标准方式0 until s.length - 1生成左闭右开区间[0, n-2]与循环需求完全吻合。Swiftclass Solution { func scoreOfString(_ s: String) - Int { let chars Array(s) var res 0 for i in 0..chars.count - 1 { res abs(Int(chars[i].asciiValue!) - Int(chars[i 1].asciiValue!)) } return res } }Swift 中String不能按下标直接访问需先转为Array(s)asciiValue返回UInt8?可选值这里用!强制解包前提是输入保证为 ASCII 字符。这也是前置知识部分强调 ASCII 范畴的原因之一。Rustimpl Solution { pub fn score_of_string(s: String) - i32 { let bytes s.as_bytes(); let mut res 0; for i in 0..bytes.len() - 1 { res (bytes[i] as i32 - bytes[i 1] as i32).abs(); } res } }as_bytes()将字符串转为[u8]逐字节访问天然适合 ASCII 处理转换为i32后再调.abs()避免无符号类型相减可能出现的下溢问题。复杂度分析原文档给出的结论如下这里补充推导依据时间复杂度O(n)——对长度为n的字符串恰好遍历一次每个位置执行常数次算术与比较操作共处理n - 1对相邻字符。空间复杂度O(1)——除输入字符串自身外仅使用一个累加变量res及循环变量不随输入规模增长分配额外内存。Swift 版本额外创建了Array(s)副本属于实现层面的常数级实为 O(n)辅助空间其余语言均为严格 O(1)。常见陷阱Common Pitfalls原文档重点提示了两个高频错误这里结合实际编码场景展开并补充第三类语言特有细节。陷阱一循环边界的 Off-by-One 错误错误写法把循环上界写成n导致在i n - 1时访问s[i 1]越界IndexOutOfBoundsException/IndexError/ 未定义行为。原因分析长度为n的字符串只有n - 1对相邻字符最后一对是(s[n-2], s[n-1])。因此循环应从0到n - 2含共迭代n - 1次。修正对照Pythonrange(len(s) - 1)Java/C/C#/JSi s.length() - 1或i s.length() - 2Kotlin0 until s.length - 1Swift/Rust0..count - 1。陷阱二忘记取绝对值错误写法直接res s[i] - s[i 1]而不包abs()。后果当s[i] s[i 1]例如zab中z与a相邻时差值为负累加到res后会使得分被抵消结果偏小甚至为负。题目要求的是绝对值之和因此无论两个字符谁大谁小差值都必须以非负形式进入累加。修正方式在所有语言中将相减结果用abs()/Math.abs/kotlin.math.abs/.abs()包裹Go 语言无int版abs需手动判断符号如原文档 Go 实现所示。陷阱三语言特有条件与类型细节Go 的无符号/有符号转换s[i]的类型是byte即uint8两个byte相减可能为负必须显式转int后运算否则可能发生无符号下溢。Swift 的可选值解包asciiValue返回可选类型遇到非 ASCII 字符如中文、emoji会得到nil此时!强解包会触发运行时崩溃若输入不保证为纯 ASCII应改为安全解包或使用unicodeScalars方案。Java/C# 的 char 算术char相减结果自动为int无需显式转换但要注意Math.abs接收的参数类型为int与返回值一致。边界情况与扩展思考在提交或本地自测时建议覆盖以下边界输入空字符串len(s) - 1 -1循环体不执行返回 0各语言对负长度的处理方式不同注意 Python 的range(-1)为空、Kotlin 的0 until -1为空区间均安全。单字符a没有相邻对得分恒为 0。大小写混合aZ→|97 - 90| 7验证了 ASCII 表中小写字母与大写字母之间存在固定间隔a - A 32。数字与符号12→|49 - 50| 1说明该算法对任意 ASCII 字符均成立。重复字符aa→ 0差值对得分无贡献。延伸思考本题是相邻元素差值求和这一模式的入门题。同一模式稍作变形即可演变为更复杂的问题例如对差值做符号判断、只统计正向差值单调性、或配合前缀和做区间查询。仓库中与字符串遍历 字符比较密切相关的题解文章还包括is-anagram.md字符计数与 ASCII 运算对应解法文件见 python/0242-valid-anagram.pylongest-common-prefix.md逐字符比较多个字符串valid-palindrome-ii.md字符级比较与双指针longest-substring-without-duplicates.md窗口内字符状态维护permutation-string.md字符频次统计。建议按先掌握单次遍历相邻元素 → 再引入双指针/窗口/计数的顺序学习逐步建立字符串类题目的解题框架。仓库中的相关资源与写作规范本文主体对应仓库中的 score-of-a-string.md其中包含前置知识、算法步骤、9 种语言的参考实现、复杂度分析与常见陷阱是 NeetCode 题解文章的标准结构模板。仓库根目录的 README.md 说明了该仓库的定位为 NeetCode 平台提供多语言题解覆盖 Python、Java、JavaScript、C、Go、Swift、C#、TypeScript、Rust、Kotlin、Ruby、C、Scala 与 Dart 共 14 种语言并维护了各题在各语言下的完成情况索引表。articles/README.md 给出了题解文章的撰写规范每篇需包含与 NeetCode 视频一致的至少一种解法、标注时间与空间复杂度、并尽可能覆盖全部相关解法。本文所述问题即遵循该规范组织内容。从当前仓库结构看该题目前以题解文章形式存在于articles/目录尚未包含对应编号的源码解法文件读者可参考本文的 9 种语言实现自行补全其他语言的等价代码Ruby、Scala、Dart、TypeScript、C 的写法差异主要在于取字符码值的 API 与abs函数名思路完全一致。【免费下载链接】leetcodeLeetcode solutions项目地址: https://gitcode.com/GitHub_Trending/leetcode1/leetcode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。