通过率 48% · 提交 661 · 通过 318
小慕在整理一份项目文档时,发现了一个由组成的记录,该字符串被N个'-'分隔成了N+1个子串。给定一个正整数K,小慕需要按照如下规则重新整理:除了第一个子串保持不变外,其余的子串每K个字符组成一个新的子串,并用'-'将它们连接起来。 对于每个新组成的子串,小慕需要判断其中小写字母和大写字母的数量:如果小写字母比大写字母多,则将这个子串中的所有大写字母转换为小写字母;如果大写字母比小写字母多,则将这个子串中的所有小写字母转换为大写字母;如果两者数量相等,则不做任何转换。
这类题属于华为 OD 机考真题方向中「100分 / 字符串」方向的高频题型,通常考察对「100分 / 字符串」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
输入为两行,第一行为参数K,第二行为字符串S.
输出转换后的字符串。
示例 1
输入示例
3 12abc-abCABc-4aB@
输出示例
12abc-abc-ABC-4aB-@
子串为12abc、abCABc、4aB@,第一个子串保留,后面的子串每3个字符一组为abC、ABc、4aB、@。 abC中小写字母较多,转换为abc ABc中大写字母较多,转换为ABC 4aB中大小写字母都为1个,不做转换 @中没有字母 连起来即12abc-abc-ABC-4aB-@
示例 2
输入示例
12 12abc-abCABc-4aB@
输出示例
12abc-abCABc4aB@
子串为12abc、abCABc、4aB@,第一个子串保留,后面的子串每12个字符一组为abCABc4aB@。这个子串中大小写字母都为4个,不做转换,连起来即12abc-abCABc4aB@。
示例 3
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
纯字符串模拟题,依据题目含义进行相应模拟即可。要注意以下几点处理:
将这整个问题分为三个小问题来解决即可: 1. 如何让初始字符串的分割和合并 2. 如何每 K 个字符一组构成子字符串 3. 如何对每个子字符串进行判断和处理
有很多同学对题意提出了不同的理解。对于
> 要求除第一个子串外,其余的子串每 K 个字符组成新的子串,并用 '-' 分隔。
这个条件,有部分同学认为其意思是对切割后的单个子字符串,而不是所有子字符串(除第一个外)构成的新字符串,进行 K 个 K 个的分组。
即对于例子
部分同学认为它的分组应该为
这确实是出题人糟糕的题目描述会带来的题意理解混淆。
遇到这种情况的时候,我们必须根据示例出发来反推题意。 如果是按照这种错误理解方式来进行的话,那么答案应该为
而不是示例输出的
对于示例二进行同样的推理,我们也能够得知如果是错误的理解方式,其答案会是
而不是正确答案
这个问题实际上包含了非常重要的启示: 既然这是考试,我们就无法决定出题人的行为,即使他们的出题水平非常差,我们也没有办法,只能够去顺应这样的结果。 在糟糕的文字表述之下,我们能做的,除了进一步提高自己对文字的阅读理解能力之外,还需要提高根据用例以及其备注,进行题意理解反推的能力,这样才能够以不变应万变。
初始字符串的分割非常简单,我们知道分割符为 "-",故我们可以直接对输入的字符串进行分割,将其分割为包含若干个子字符串的列表 lst,其代码为
接下来,我们需要把除了第一个子字符串之外的其他剩余所有字符串合并为 s,方便后续操作。注意这里的合并符直接选择空字符串 "" 即可,其代码为
接下来,我们希望能够对 s 里的字符以 K 为长度进行分组,得到每一个子字符串 sub_s。 我们可以在 range() 中选择步长为 K 来遍历每一个子字符串的起始索引 idx。 显然,idx 的取值就会是 0, K, 2*K, 3*K... 以此类推。
在 Python 中,我们可以通过切片来获得一个字符串的长度为 K 的子字符串,即 sub_s = s[idx:idx+K]。 注意到,如果 len(s) 如果不是恰好是 K 的倍数的话,最后一个子字符串的长度是不足 K 的。 根据题意,我们需要保留最后一个子字符串的原长度。
但 Python 的切片是非常宽容的。当我们选择 sub_s = s[idx:idx+K] 时,如果 idx+K 大于字符串 s 的长度 len(s),也不会发生报错。这个切片会直接取完原字符串 s 的剩余部分,用 len(s) 来作为终止位置。 故该过程的代码为
如果你对 sub_s = s[idx:idx+K] 的越界问题实在不放心,或者你是使用 Java 或者 C++ 等其他语言,可以将终止位置 idx+K 替换为 min(idx+K, len(s)),这样就能够确保切片的终止位置,不会比字符串长度 len(s) 更大。 其代码为
对于上述得到的每一个子字符串 sub_s,我们都需要去进行判断和修改。 这是一个额外的子问题,可以抽象成 get_res() 来处理。
我们可以用两个变量 upper_num 和 lower_num 来分别记录 sub_s 中大写、小写的字母的个数。
接着遍历 sub_s 中的每一个字符 ch,如果
ch 是小写字母,则 lower_num 的个数增加ch 是大写字母,则 upper_num 的个数增加ch 是其他无关字符,则不做任何修改注意,字符 ch 的大小写判断可以直接使用字符串方法 islower() 和 isupper() 来实现,也可以通过字符串比较的方式 "a" <= ch <= "z" 和 "A" <= ch <= "Z" 来实现。
退出循环后,我们判断两个变量 upper_num 和 lower_num 之间的大小关系。若
sub_ssub_s 中所有小写字母都改为大写的字符串,使用字符串方法 upper() 实现sub_s 中所有大写字母都改为小写的字符串,使用字符串方法 lower() 实现故 get_res() 的整体代码为
那么在主函数代码中,我们通过将得到的每一个子字符串 sub_s 传入函数 get_res(),就可以获得每一个子字符串处理后的结果了。即 ans.append(get_res(sub_s))。
复杂度分析 设 L 为输入字符串的总长度。先用 split 按分隔符切割、再用 join 把第一段之外的子串合并成 s,这两步各扫描一遍字符串,均为 O(L)。随后以步长 K 遍历 s:每个子串 sub_s 在 get_res 中被扫描一次统计大小写字母个数,必要时再做一次 lower 或 upper 转换——每个字符总共只被处理常数次,这一段整体也是 O(L)。因此总时间复杂度为 O(L)。空间上,合并串 s、结果列表 ans 与输入同量级,空间复杂度为 O(L)。瓶颈只是对字符串的若干次线性扫描,没有更高阶的循环。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
输入示例
5 12abc-abCABc-4aB@
输出示例
12abc-ABCAB-c4ab@
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有