通过率 54% · 提交 686 · 通过 369
小慕正在参加一个单词接龙挑战赛。接龙的规则如下: 用于接龙的单词,其首字母必须与前一个单词的尾字母相同 当有多个单词的首字母相同时,选择长度最长的单词;若长度也相同,则选择最小的单词;已经使用过的单词不能再次使用 现在小慕得到了一个全部由小写字母组成的单词数组,并指定其中一个单词作为起始单词,开始进行单词接龙, 请你帮小慕输出最长的,单词串由单词依次拼接而成,中间没有空格。
这类题属于华为 OD 机考真题方向中「100分 / 排序」方向的高频题型,通常考察对「100分 / 排序」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
输入的第一行为一个非负整数,表示起始单词在数组中的索引K,0 <= K < N 输入的第二行为一个非负整数,表示单词的个数N; 接下来的N行,分别表示单词数组中的单词 备注: 单词个数N的取值范围为[1,20]; 单个单词的长度的取值范围为[1,30]
输出一个字符串,表示最终拼接的单词串
示例 1
输入示例
0 6 word dd da dc dword d
输出示例
worddwordda
先确定起始单词word,再接以d开头的且长度最长的单词dword,剩余以d开头且长度最长的有dd、da、dc,则取字典序最小的da,所以最后输出worddwordda。
示例 2
输入示例
4 6 word dd da dc dword d
输出示例
dwordda
先确定起始单词dword,剩余以d开头且长度最长的有dd、da. dc,则取字典序最小的da,所以最后输出dwordda。
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
首先必须避免一个题目理解上的误区。 假设已知当前的已经接龙好的字符串为 ans,其最后一个字符为 ans[-1]。 那么下一个接龙的单词,是首字母为 ans[-1] 的长度尽可能大、字典序尽可能小的那个单词。
换句话说,对于已经接龙好的字符串为 ans,其下一个接龙的单词是唯一确定的。
此处可能存在另一种理解,就是接龙过程中选择单词的策略是不确定的,目的是使得最终接龙完毕的字符串最长。如果是这种理解,则示例二的答案会是 dwordddda,需要使用动态规划来完成,难度陡升。
由于每一次接龙之后,下一个接龙的单词的首字母就是当前字符串的最后一个字母 ans[-1]。 假设以字母 ans[-1] 为开头的单词已经储存为一个列表 lst。 我们需要找到 lst 中,长度尽可能大、字典序尽可能小的那个单词。 可以使用 lambda 匿名函数对 lst 进行排序,lst 末尾的元素就是要延长的单词。
上述排序写法可能不容易理解,举个例子就好理解了。 对于以 "a" 为开头的若干单词 lst = ["a", "ab", "ac", "abd", "abc"],我们期望其获得如下排序:
lst.sort(key = lambda x: (-len(x), x)) 的含义是,先按照长度从大到小排序,长度相等的时候再按照字典序从小到大排序。这样排序后,具有最高优先级的单词就排在 lst 的开头了。 为了使得具有最高优先级的单词排在 lst 的末尾,方便使用 pop() 操作取出,我们在排序的过程中再设置参数 reverse = True,即 lst.sort(key = lambda x: (-len(x), x), reverse = True),这样就能达到排序要求。
很显然,所有具有同一个首字母的单词都可以分为同一组,放在同一个列表中进行排序。 所以我们可以构建哈希表 dic,key 为首字母 first_ch,value 为以字母 first_ch 为首字母开头的若干单词构成的列表。对应的代码如下:
除此之外,dic 中的每一个列表都要再按照前一小点中的排序方案进行排序,即:
譬如对于示例二,构建出来的 dic 如下:
在上述预处理过程完成之后,剩下就是按照题意进行单词接龙的模拟过程了。
显然这里的循环过程不应该使用 for 循环(因为不知道接龙次数),应该使用 while 循环。 当前字符串 ans 的最后一个字母 ans[-1] 是下一个单词的首字母,因此我们 while 持续进行的条件是,首字母 ans[-1] 在 dic 中还能找到对应的单词,即 len(dic[ans[-1]]) > 0。
在循环中,由于前面预处理已经将每一个单词列表都按照要求排序完毕,我们需要弹出列表 dic[ans[-1]] 中的最后一个单词,作为接下来延长的单词 following_word = dic[ans[-1]].pop()。
对 ans 进行延长就是直接 ans += following_word。
故代码为:
复杂度分析 设单词个数为 n,最长单词长度为 m,所有单词的总字符数为 L(L <= n*m)。
总时间复杂度 O(n * m * log n),空间复杂度 O(L),即哈希表里存放全部单词的开销。得益于"先把每组排好序、接龙时只从末尾弹出"的设计,模拟阶段本身是线性的。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有