单词拆分问题的自顶向下动态规划代码的时间复杂度是多少?
单词拆分自顶向下动态规划解法时间复杂度分析
先明确变量定义:
- n 为输入字符串
s的长度 - k 为字典
wordDict的大小 - L 为字典中单词的平均长度,W 为字典中单词的最大长度
核心逻辑说明
你贴的代码是带备忘录的自顶向下动态规划实现:
- 用参数
l表示当前需要匹配的子串在s中的起始下标,备忘录m存储每个下标l开始的子串是否可以被合法拆分的结果,避免重复计算 - 对于每个
l,遍历字典中所有单词,调用match函数判断该单词是否和s从l开始的前缀匹配,匹配成功则递归判断l + 单词长度位置开始的子串是否可以拆分 - 只要找到一条合法拆分路径就返回
true,所有单词遍历完都没有合法路径则将m[l]设为false并返回
时间复杂度计算
- 总状态数:
l的取值范围是 0 到 n,最多有 n+1 个不同的状态,每个状态只会被计算一次,计算后就存入备忘录,后续直接读取无需重复计算 - 单状态开销:每个状态需要遍历字典的 k 个单词,每个单词的
match匹配操作时间复杂度等于单词长度,平均为 O(L),最坏为 O(W),因此每个状态的处理开销为 O(k*L) - 额外开销:代码中使用
std::map实现备忘录,单次查找的时间复杂度为 O(logn),这部分开销远低于主逻辑开销,可以忽略;如果替换为unordered_map查找开销为 O(1),也不影响主时间复杂度
综上,这段代码的时间复杂度为 O(n * k * L),如果按字典单词最大长度计算则为 O(n * k * W)。
内容的提问来源于stack exchange,提问作者Ranju
相关产品推荐
相关产品推荐

