SWE · Coding

TikTok Word Break:可重复使用词典词,怎样避免贪心误判?

以可达前缀为DP状态,在Trie内探索所有词结尾,解释最长词贪心失败、空词和结果输出。

题目重点:以可达前缀为DP状态,在Trie内探索所有词结尾,解释最长词贪心失败、空词和结果输出。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 按顺序覆盖整个目标字符串,不重排字符;词典词可重复,空词忽略,重复词去重。
  • 空目标字符串按零个词拼接返回True;比较按code point、区分大小写。
  • 返回布尔结果,不列出所有句子;列举版的输出规模可指数增长。

解题路线

  1. 令reachable[i]表示前i个字符已经能完整分词。reachable[0]=True,只有已可达位置才发起下一个词匹配;不存在的前缀不能因为局部匹配了单词就转True。
  2. 把词典建Trie,从每个可达i沿text[i:]前进,遇终止标记就把对应j+1设True;继续走,因为短词和长词都可能是有效下一步。
  3. 贪心选最长词不可靠:text=abcdef、词典[abcd,abc,def],先abcd会卡在ef,但abc+def成功。DP保留所有可达结尾而非选一个最长匹配。
  4. 正确性按前缀长度归纳:每次转移来自可分前缀和一个词典词,产生合法拼接;任意合法完整拼接最后一词的开始前缀必可达,该词沿Trie会被走到,所以不会漏。
  5. 词典空词若用朴素递归可能形成不推进位置的循环;本文直接忽略,不改变布尔可分性。terminal用私有object,避免真实字符和特殊字符串标签冲突。
  6. 复杂度还要考虑实现细节:若反复切text[i:j]再哈希,构造/哈希字符串会引入额外字符成本。Trie按字符走可避免这些切片,但每个可达位置仍可能走到最长词长度。
  7. 需要一组分词时记录首次成功前驱;需要所有分词时DP只帮判可达,再回溯输出,答案数本身不可忽略。流式输入若词长度有上限可做窗口状态,但全文词典匹配合同要保持。

手动走一遍

catsanddog可用cats+and+dog,也可cat+sand+dog,只问布尔时均证明True。aaaa与词典[aa]可重复两次,不能因词典仅一个aa就返回False。abcdef的长词贪心例说明不能只接受一个路径。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

"""Boolean segmentation with reusable nonempty dictionary words.
Empty text is segmentable; empty words ignored, duplicate words deduplicated.
"""


def can_segment(text, words):
    root = {}
    terminal = object()
    for word in set(words):
        if not word:
            continue
        node = root
        for char in word:
            node = node.setdefault(char, {})
        node[terminal] = True
    reachable = [False] * (len(text) + 1)
    reachable[0] = True
    for i in range(len(text)):
        if not reachable[i]:
            continue
        node = root
        for j in range(i, len(text)):
            if text[j] not in node:
                break
            node = node[text[j]]
            if terminal in node:
                reachable[j + 1] = True
    return reachable[-1]

复杂度

设词典总字符S、最长词长L、目标长n,建Trie期望O(S),DP遍历O(n·min(n,L))最坏时间,空间O(S+n)。输出所有拆分时再加答案构建成本。

易错点与追问

容易失分的边界

  • 词典可复用却把用过词删除。
  • 最长匹配贪心。
  • 空词导致无限递归。
  • 声称哈希子串是免费O(1)。

继续深挖

  • 如何返回一组拆分或最少词数?
  • 能否计数且对大数取模?
  • 大小写/Unicode归一化在哪一步做?
  • 词典频繁变化如何复用索引?
✓已复制微信号!