通过率 51% · 提交 637 · 通过 327
小慕正在开发一款第一人称射击游戏的角色移动系统。玩家通过键盘上的 `A`、`S`、`D`、`W` 四个按键控制角色分别向左、向后、向右、向前移动一步,从而完成走位。 小慕发现,如果玩家按动一定次数的键盘后,各个方向的移动步数恰好相等,那么角色必定会回到原点,小慕将这种走位称为。 现在小慕拿到了一段玩家的走位记录(例如:`ASDA`),他希望通过替换其中一段(可以替换成任意相同长度的走位),使得整段走位变成一个完美走位。 请你帮小慕计算出待替换的连续走位的最小可能长度。如果原走位本身已经是完美走位,则返回 `0`。 备注 1. 走位长度 1 ≤ s.length ≤ 10^5 2. s.length 是 4 的倍数 3. s 中只含有 A、S、D、W
这类题属于华为 OD 机考真题方向中「100分 / 滑动窗口」方向的高频题型,通常考察对「100分 / 滑动窗口」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
输入为由键盘字母表示的走位s,例如:ASDA
输出为待更换的连续走位的最小可能长度
示例 1
输入示例
AASW
输出示例
1
需要把一个 A 更换成 D,这样可以得到 ADSW 或者 DASW。
示例 2
输入示例
ASDW
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
注意,本题 替换子串得到平衡字符串 以及 最小覆盖子串 几乎完全一致。 重点在于如何将原问题转化为 覆盖子串 的问题。
题目有两个重要条件:
1. 完美走位字符串 是指字符串中 A、S、D、W 四种字符出现次数相等的字符串 2. s.length 是 4 的倍数
对于长度为 len(s) 的原字符串 s 来说,为了使其转变为一个 完美走位字符串,其中 A、S、D、W 四种字符出现次数应该均为:
原字符串 s 中各个字符出现的次数可以用哈希表 cnt_s = Counter(s) 进行统计。 对于出现次数多于 num = len(s) // 4 的字符 ch,应该修改 cnt_s[ch] - len(s) // 4 个字符为其他出现次数少于 num = len(s) // 4 的字符,才能够使得 s 变为一个 完美走位字符串。
以示例四为例,s = "AAAAADDD",字符 "A" 出现的次数为 5,字符 "D" 应该修改 3,而 num = len(s) // 4 = 2,需要修改 3 个 "A" 和 1 个 "D" 为剩余两种字符,才能使得 s 变为完美走位字符串。 故我们需要找到包含 3 个 "A" 和 1 个 "D" 的 最短子串。
因此这个问题就转变为了:找到覆盖 `cnt_s[ch] - len(s) // 4` 个的字符 `ch`(`ch` 满足条件 `cnt_s[ch] > len(s) // 4`)的最短子串。 需要覆盖的子串中所出现的字符以及次数,可以用另一个哈希表 cnt_sub 储存。
那么这个问题就和 最小覆盖子串 完全一致了,直接 滑窗三问三答 解决即可。
上述逻辑整理为代码即:
复杂度分析 设走位记录长度为 n。统计原字符串中各字符出现次数的 cnt_s 需要遍历一次字符串,O(n);由 cnt_s 导出需要被替换覆盖的字符表 cnt_sub 只涉及至多 4 种字符,O(1)。滑窗阶段,right 从头到尾走一遍,left 只会单调右移、累计移动量不超过 n,每个字符至多进窗一次、出窗一次;每一步的 check 只比较 cnt_sub 中至多 4 个键(字符只有 A、S、D、W 四种),是常数时间。因此滑窗整体为 O(n),总时间复杂度 O(n)。空间上,cnt_s、cnt_sub、cnt_win 三个哈希表都至多存 4 个键,为 O(1);算上读入的字符串本身则是 O(n)。题目给出 n 上限为 10^5,线性做法轻松通过。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
输出示例
0
已经是完美走位了。
示例 3
输入示例
AAAA
输出示例
3
可以替换后 3 个 A,得到 ASDW。
示例 4
输入示例
AAAAADDD
输出示例
4
时间限制 1000 ms · 内存限制 128 MB
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有