2026-07-20:镜像频次距离。用go语言,给定一个仅包含小写英文字母和数字的字符串。每个字符都有一个镜像字符:对于字母,‘a’ 的镜像是 ‘z’,‘b’ 的镜像是 ‘y’,依此类推,直至 ‘z’ 的镜像是 ‘a’;对于数字,‘0’ 的镜像是 ‘9’,‘1’ 的镜像是 ‘8’,依此类推,直至 ‘9’ 的镜像是 ‘0’。用 freq(x) 表示字符 x 在字符串中出现的次数。
对于字符串中实际出现过的每一种字符 c,设它的镜像为 m,计算该字符出现次数与其镜像出现次数的绝对差 |freq© - freq(m)|。镜像对 (c, m) 与 (m, c) 视为同一对,在计算总和时每个不同的镜像对只计算一次。最后返回所有不同镜像对的绝对差之和。
1 <= s.length <= 500000。
s 仅由小写英文字母和数字组成。
输入: s = “ab1z9”。
输出: 3。
解释:
对于每个镜像对:
| c | m | freq© | freq(m) | |freq© - freq(m)| |
|---|---|---|---|---|
| a | z | 1 | 1 | 0 |
| b | y | 1 | 0 | 1 |
| 1 | 8 | 1 | 0 | 1 |
| 9 | 0 | 1 | 0 | 1 |
因此,答案是 0 + 1 + 1 + 1 = 3。
题目来自力扣3889。
第一步:统计字符出现频次
创建计数数组
代码中定义了一个长度为'z' + 1(即 123)的整型数组cnt,用于存储每个字符的出现次数。这个数组的大小足够覆盖所有小写字母'a'到'z'的 ASCII 码值,同时也能容纳数字字符'0'到'9'的 ASCII 码值(它们在 ASCII 表中的位置也在这个范围内)。遍历输入字符串
对字符串s中的每个字符ch,执行cnt[ch]++,将对应 ASCII 码位置的计数值加 1。
例如对于输入"ab1z9":cnt['a'] = 1cnt['b'] = 1cnt['1'] = 1cnt['z'] = 1cnt['9'] = 1
其他位置保持默认值 0。
第二步:计算字母镜像对的绝对差之和
确定镜像对的范围
小写字母的镜像关系是'a'↔'z','b'↔'y',…,一直到'm'↔'n'。总共 13 对(因为 26 个字母两两配对)。遍历字母镜像对
代码中通过for i := range 13循环 13 次,每次计算:- 当前字母
'a' + i - 它的镜像字母
'z' - i
这样做的好处是每个镜像对只被计算一次,不会重复计算
(c, m)和(m, c)。- 当前字母
计算绝对差并累加
对于每对(c, m),计算它们在cnt数组中的频次差的绝对值abs(cnt[c] - cnt[m]),并累加到结果ans中。
以"ab1z9"为例:'a'和'z'的频次分别为 1 和 1,差为 0。'b'和'y'的频次分别为 1 和 0,差为 1。- 其余字母对的频次都是 0,差为 0。
此步累加得到0 + 1 = 1。
第三步:计算数字镜像对的绝对差之和
确定镜像对的范围
数字的镜像关系是'0'↔'9','1'↔'8',…,一直到'4'↔'5'。总共 5 对(10 个数字两两配对)。遍历数字镜像对
代码中通过for i := range 5循环 5 次,每次计算:- 当前数字
'0' + i - 它的镜像数字
'9' - i
同样,每个镜像对只计算一次。
- 当前数字
计算绝对差并累加
对于每对(d, m),计算abs(cnt[d] - cnt[m])并累加到ans。
以"ab1z9"为例:'0'和'9'的频次分别为 0 和 1,差为 1。'1'和'8'的频次分别为 1 和 0,差为 1。- 其余数字对的频次都是 0,差为 0。
此步累加得到1 + 1 = 2。
第四步:返回最终结果
将字母部分的结果(1)和数字部分的结果(2)相加,得到最终答案 3,并通过函数返回。
时间复杂度分析
- 频次统计阶段:遍历字符串
s一次,时间复杂度为O(n),其中n为字符串长度,n ≤ 500,000。 - 镜像对计算阶段:固定遍历 13 个字母对和 5 个数字对,总共 18 次常数次操作,时间复杂度为O(1)。
总时间复杂度:O(n)。
额外空间复杂度分析
- 使用了一个长度为 123 的整型数组
cnt来统计频次,这个大小是常数,不随输入规模增长。 - 其他变量(如循环索引、累加变量)占用常量空间。
总额外空间复杂度:O(1)。
Go完整代码如下:
packagemainimport("fmt")funcmirrorFrequency(sstring)(ansint){cnt:=['z'+1]int{}for_,ch:=ranges{cnt[ch]++}fori:=range13{ans+=abs(cnt['a'+i]-cnt['z'-i])}fori:=range5{ans+=abs(cnt['0'+i]-cnt['9'-i])}return}funcabs(xint)int{ifx<0{return-x}returnx}funcmain(){s:="ab1z9"result:=mirrorFrequency(s)fmt.Println(result)}Python完整代码如下:
# -*-coding:utf-8-*-defmirror_frequency(s:str)->int:cnt=[0]*128# 覆盖 ASCII 范围内所有字符forchins:cnt[ord(ch)]+=1ans=0# 处理字母 a-zforiinrange(13):ans+=abs(cnt[ord('a')+i]-cnt[ord('z')-i])# 处理数字 0-9foriinrange(5):ans+=abs(cnt[ord('0')+i]-cnt[ord('9')-i])returnansdefmain():s="ab1z9"result=mirror_frequency(s)print(result)if__name__=="__main__":main()C++完整代码如下:
#include<iostream>#include<string>#include<cmath>usingnamespacestd;intmirrorFrequency(conststring&s){intcnt[128]={0};// 覆盖 ASCII 范围内所有字符for(charch:s){cnt[ch]++;}intans=0;// 处理字母 a-zfor(inti=0;i<13;i++){ans+=abs(cnt['a'+i]-cnt['z'-i]);}// 处理数字 0-9for(inti=0;i<5;i++){ans+=abs(cnt['0'+i]-cnt['9'-i]);}returnans;}intmain(){string s="ab1z9";intresult=mirrorFrequency(s);cout<<result<<endl;return0;}