← 返回博客列表
Bloomberg

Bloomberg 面试题:根据字典把无空格字符串切分成句子

2025-12-12

题目描述

给定一个词典和一个不含空格的字符串,编写方法返回一个正确插入空格的字符串,使每个单词都在词典中。

示例

输入: 
  字符串: "bloombergisfun"
  词典: ["bloom", "bloomberg", "is", "fun"]

输出: "bloomberg is fun"

解题思路

这是经典的 Word Break 问题,可以用多种方法解决:

方法一:贪心(最长匹配优先)

对于简单场景,贪心选择最长匹配的单词:

def word_break_greedy(s: str, word_dict: set) -> str:
    result = []
    i = 0
    
    while i < len(s):
        # 尝试匹配最长的单词
        matched = False
        for j in range(len(s), i, -1):
            word = s[i:j]
            if word in word_dict:
                result.append(word)
                i = j
                matched = True
                break
        
        if not matched:
            return ""  # 无法切分
    
    return ' '.join(result)

方法二:动态规划 + 回溯(推荐)

先用 DP 确认是否可切分,再用回溯构造结果:

def word_break(s: str, word_dict: list) -> str:
    word_set = set(word_dict)
    n = len(s)
    
    # dp[i] 表示 s[0:i] 是否可以被切分
    dp = [False] * (n + 1)
    dp[0] = True
    
    # parent[i] 记录从哪个位置跳转到 i
    parent = [-1] * (n + 1)
    
    for i in range(1, n + 1):
        for j in range(i):
            if dp[j] and s[j:i] in word_set:
                dp[i] = True
                parent[i] = j
                break  # 找到一个即可
    
    if not dp[n]:
        return ""
    
    # 回溯构造结果
    words = []
    i = n
    while i > 0:
        j = parent[i]
        words.append(s[j:i])
        i = j
    
    return ' '.join(reversed(words))

方法三:返回所有可能的切分

如果有多种切分方式,返回所有结果:

def word_break_all(s: str, word_dict: list) -> list:
    word_set = set(word_dict)
    memo = {}
    
    def dfs(start: int) -> list:
        if start == len(s):
            return [[]]
        
        if start in memo:
            return memo[start]
        
        result = []
        for end in range(start + 1, len(s) + 1):
            word = s[start:end]
            if word in word_set:
                for rest in dfs(end):
                    result.append([word] + rest)
        
        memo[start] = result
        return result
    
    return [' '.join(words) for words in dfs(0)]

# 示例
print(word_break_all("bloombergisfun", ["bloom", "bloomberg", "is", "fun"]))
# 输出: ["bloom berg is fun", "bloomberg is fun"] 或类似

复杂度分析

面试要点

  1. 确认输出格式:返回一个还是所有切分方式
  2. 无法切分的处理:返回空字符串还是抛异常
  3. 大小写敏感:是否需要忽略大小写

需要面试辅助服务?联系我们

需要面试真题? 立刻联系微信 Coding0201,获得真题