【LeetCode】139. 单词拆分

leetcode

 

解题思路

本问题可以通过 ​​动态规划​​ 结合 ​​哈希表优化​​ 解决。核心思想是定义 dp[i] 表示字符串 s 的前 i 个字符是否可以被字典中的单词拼接而成。通过预处理字典中的单词,利用哈希表快速查询子串,并结合动态规划逐步推导结果。


关键步骤

  1. ​​预处理字典​​:

    • 将字典中的单词存入哈希表,便于快速查询子串是否存在。
    • 记录字典中单词的最大长度 maxLen,减少无效的子串检查。
  2. ​​动态规划初始化​​:

    • 定义 dp 数组,dp[0] = true 表示空字符串可以被拼接。
  3. ​​状态转移​​:

    • 遍历字符串 s 的每个位置 i(从 1 到 n)。
    • 对于每个位置 i,检查所有可能的子串长度 l(从 1 到 maxLen)。
    • 若子串 s[j:i] 存在于字典且 dp[j] 为 true,则标记 dp[i] = true
  4. ​​结果判断​​:

    • 最终返回 dp[n]n 为 s 的长度)。

复杂度分析

  • ​​时间复杂度​​:O(n * maxLen)
    其中 n 是字符串 s 的长度,maxLen 是字典中最长单词的长度。每个位置最多检查 maxLen 次子串。
  • ​​空间复杂度​​:O(n + m)
    n 为 dp 数组的长度,m 为字典中单词的总数(哈希表存储)。

代码实现

func wordBreak(s string, wordDict []string) bool {
    // 预处理字典:存储单词并记录最大长度
    wordSet := make(map[string]bool)
    maxLen := 0
    for _, word := range wordDict {
        wordSet[word] = true
        if len(word) > maxLen {
            maxLen = len(word)
        }
    }
    
    n := len(s)
    dp := make([]bool, n+1)
    dp[0] = true // 空字符串初始化为true
    
    for i := 1; i <= n; i++ {
        // 检查所有可能的子串长度(1到maxLen)
        start := max(0, i - maxLen) // 防止越界
        for j := start; j < i; j++ {
            if dp[j] && wordSet[s[j:i]] {
                dp[i] = true
                break // 找到一个可行解即可跳出
            }
        }
    }
    return dp[n]
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

代码注释

  1. ​​字典预处理​​
    使用哈希表存储字典中的单词,并记录最长单词长度,减少无效子串遍历。
  2. ​​动态规划边界​​
    dp[0] = true 表示空字符串的初始状态。
  3. ​​状态转移优化​​
    通过 start := max(0, i - maxLen) 限制子串检查范围,避免无效遍历。
  4. ​​子串查询​​
    利用哈希表 wordSet 快速判断子串 s[j:i] 是否存在于字典。

运行示例

func main() {
    fmt.Println(wordBreak("leetcode", []string{"leet", "code"}))      // true
    fmt.Println(wordBreak("applepenapple", []string{"apple", "pen"})) // true
    fmt.Println(wordBreak("catsandog", []string{"cats", "dog", "sand", "and", "cat"})) // false
}

算法扩展

    1. ​​字典树优化​​
      若字典规模极大,可用字典树(Trie)替代哈希表,将子串查询时间优化为 O(l)l 为子串长度)。
    2. ​​剪枝策略​​
      在动态规划过程中,若 dp[i] 已为 true,可提前终止后续子串检查,进一步减少计算量。
posted @ 2025-04-24 21:59  云隙之间  阅读(33)  评论(0)    收藏  举报