检查列表单词是否为另一列表单词前缀:求高效简洁实现方案
更高效简洁的前缀检查实现方案
当然有!这种“验证所有前缀是否存在于目标单词列表中”的需求,我们可以根据数据规模选择几种更简洁、性能更优的实现方式,告别复杂的流程。
1. 极简写法:适合小规模列表
如果你的两个列表规模不大,用Python内置的all()和any()结合生成器表达式就能搞定,代码简洁到一行核心逻辑,而且是惰性求值——一旦找到不符合条件的前缀就会立即停止,不用遍历全部元素。
def all_prefixes_exist(prefixes, words): # all()确保每个前缀都满足条件,any()检查是否有单词以该前缀开头 return all(any(word.startswith(prefix) for word in words) for prefix in prefixes)
举个例子测试下:
prefix_list = ["app", "ban"] word_list = ["apple", "banana", "orange"] print(all_prefixes_exist(prefix_list, word_list)) # 输出 True prefix_list = ["app", "gra"] print(all_prefixes_exist(prefix_list, word_list)) # 输出 False
2. 排序+二分查找:适合中等规模列表
如果列表规模中等,暴力遍历的O(MN)复杂度会有点慢,这时候可以先对目标单词列表排序,再用二分查找快速定位可能匹配的单词,把时间复杂度降到O(N log N + M(log N + K))(K是前缀的平均长度)。
import bisect def all_prefixes_exist(prefixes, words): sorted_words = sorted(words) for prefix in prefixes: # 找到第一个大于等于当前前缀的单词索引 idx = bisect.bisect_left(sorted_words, prefix) # 检查索引处或前一个单词是否以当前前缀开头 found = False if idx < len(sorted_words) and sorted_words[idx].startswith(prefix): found = True elif idx > 0 and sorted_words[idx-1].startswith(prefix): found = True if not found: return False return True
这个方法不需要额外的数据结构,代码复杂度适中,性能比暴力法提升明显。
3. 前缀树(Trie):适合大规模/高频查询场景
如果你的单词列表非常大,或者需要频繁进行这类前缀检查,构建前缀树(Trie)是最优选择。它把单词的公共前缀整合在一起,每个前缀的检查只需要遍历自身的字符,时间复杂度降到O(NL + MK)(L是单词的平均长度)。
class TrieNode: def __init__(self): self.children = {} # 这里不需要标记单词结尾,因为我们只需要前缀存在,不需要单词完全匹配 def build_trie(words): root = TrieNode() for word in words: node = root for char in word: if char not in node.children: node.children[char] = TrieNode() node = node.children[char] return root def is_prefix_valid(prefix, trie_root): node = trie_root for char in prefix: if char not in node.children: return False node = node.children[char] return True def all_prefixes_exist(prefixes, words): trie = build_trie(words) return all(is_prefix_valid(p, trie) for p in prefixes)
构建一次Trie后,后续的查询会非常快,适合需要多次重复查询的场景。
总结选择建议
- 小规模数据:优先选极简写法,代码最少最省心
- 中等规模数据:排序+二分查找,平衡性能和代码复杂度
- 大规模/高频查询:前缀树,性能最优
内容的提问来源于stack exchange,提问作者Nicholas Nickleby
相关产品推荐
相关产品推荐

