2025-07-19:计算字符串的镜像分数。用go语言,给定一个字符串 s,定义每个英文字母的“镜像”为字母表反转后对应的位置字
【摘要】 2025-07-19:计算字符串的镜像分数。用go语言,给定一个字符串 s,定义每个英文字母的“镜像”为字母表反转后对应的位置字母,例如:‘a’ 的镜像是 ‘z’,‘b’ 的镜像是 ‘y’,依此类推。初始时,字符串中所有字符都未被标记,且总分为 0。按照以下规则处理字符串:从左到右遍历每个字符,假设当前索引为 i。对于当前字符 s[i],在其左边(索引小于 i 且未标记的字符中)寻找一个距离...
2025-07-19:计算字符串的镜像分数。用go语言,给定一个字符串 s,定义每个英文字母的“镜像”为字母表反转后对应的位置字母,例如:‘a’ 的镜像是 ‘z’,‘b’ 的镜像是 ‘y’,依此类推。
初始时,字符串中所有字符都未被标记,且总分为 0。按照以下规则处理字符串:
-
从左到右遍历每个字符,假设当前索引为 i。
-
对于当前字符 s[i],在其左边(索引小于 i 且未标记的字符中)寻找一个距离最近的字符 s[j],该字符是 s[i] 的镜像。
-
如果找到了这样的字符 s[j],则将 s[i] 和 s[j] 标记为已处理,且总分增加 i - j。
-
如果未找到符合条件的字符,跳过当前字符,继续处理下一个字符。
最终,返回所有匹配操作累积的总分。
1 <= s.length <= 100000。
s 仅由小写英文字母组成。
输入: s = “aczzx”。
输出: 5。
解释:
i = 0。没有符合条件的下标 j,跳过。
i = 1。没有符合条件的下标 j,跳过。
i = 2。距离最近的符合条件的下标是 j = 0,因此标记下标 0 和 2,然后将总分加上 2 - 0 = 2 。
i = 3。没有符合条件的下标 j,跳过。
i = 4。距离最近的符合条件的下标是 j = 1,因此标记下标 1 和 4,然后将总分加上 4 - 1 = 3 。
题目来自力扣3412。
分步骤描述过程:
-
初始化:
- 创建一个长度为26的切片
arr,每个元素是一个空的整数切片(栈),用于存储每个字母(a-z)在字符串中出现的未匹配索引。 - 初始化结果
res为0,用于累计总分。 - 获取字符串长度
n。
- 创建一个长度为26的切片
-
遍历字符串:
- 从字符串的第一个字符开始,依次处理每个字符
s[i](索引i从0到n-1)。
- 从字符串的第一个字符开始,依次处理每个字符
-
处理当前字符:
- 计算当前字符
s[i]对应的字母索引v = int(s[i] - 'a')(例如,'a'对应0,'b'对应1,…,'z'对应25)。 - 计算当前字符的镜像字母索引
rev = 25 - v(例如,'a'的镜像'z'对应25,'b'的镜像'y'对应24,依此类推)。
- 计算当前字符
-
查找镜像字符:
- 检查
arr[rev]是否非空(即是否有未匹配的镜像字符):- 如果
arr[rev]非空,弹出栈顶元素j(即最近的未匹配镜像字符的索引),计算i - j并加到res中。 - 如果
arr[rev]为空,将当前字符的索引i压入arr[v]的栈中(表示当前字符未被匹配,等待后续可能的匹配)。
- 如果
- 检查
-
具体示例
s = "aczzx"的处理过程:i = 0:s[0] = 'a',v = 0,rev = 25('z')。arr[25]为空,将0压入arr[0]。arr[0] = [0]。i = 1:s[1] = 'c',v = 2,rev = 23('x')。arr[23]为空,将1压入arr[2]。arr[2] = [1]。i = 2:s[2] = 'z',v = 25,rev = 0('a')。arr[0]非空([0]),弹出j = 0,计算2 - 0 = 2,res = 2。arr[0]变为空。i = 3:s[3] = 'z',v = 25,rev = 0('a')。arr[0]为空,将3压入arr[25]。arr[25] = [3]。i = 4:s[4] = 'x',v = 23,rev = 2('c')。arr[2]非空([1]),弹出j = 1,计算4 - 1 = 3,res = 5。arr[2]变为空。
-
最终结果:
- 遍历结束后,
res = 5,与题目描述一致。
- 遍历结束后,
时间复杂度和空间复杂度:
- 时间复杂度:O(n),其中
n是字符串长度。每个字符仅被处理一次,且栈操作(压入和弹出)均为 O(1)。 - 额外空间复杂度:O(n),最坏情况下所有字符都未被匹配,此时
arr中的栈总大小为n。
Go完整代码如下:
package main
import (
"fmt"
)
func calculateScore(s string) int64 {
// 创建一个切片,元素为 int 类型的栈,表示每个字母的索引栈
arr := make([][]int, 26)
for i := range arr {
arr[i] = []int{}
}
res := int64(0)
n := len(s)
for i := 0; i < n; i++ {
v := int(s[i] - 'a')
rev := 25 - v // 镜像字母对应的索引
if len(arr[rev]) > 0 {
// 弹出最近的镜像字符索引
j := arr[rev][len(arr[rev])-1]
arr[rev] = arr[rev][:len(arr[rev])-1]
res += int64(i - j)
} else {
// 没有找到镜像字符,当前字符入栈
arr[v] = append(arr[v], i)
}
}
return res
}
func main() {
s := "aczzx"
result := calculateScore(s)
fmt.Println(result)
}

Python完整代码如下:
# -*-coding:utf-8-*-
def calculateScore(s: str) -> int:
# 创建一个列表,元素为栈(列表),表示每个字母的位置索引栈
arr = [[] for _ in range(26)]
res = 0
n = len(s)
for i, ch in enumerate(s):
v = ord(ch) - ord('a')
rev = 25 - v # 镜像字母对应的索引
if arr[rev]:
# 弹出最近的镜像字符索引
j = arr[rev].pop()
res += i - j
else:
# 没有找到镜像字符,当前字符入栈
arr[v].append(i)
return res
if __name__ == "__main__":
s = "aczzx"
result = calculateScore(s)
print(result)

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)