day46 ● 139.单词拆分

132 阅读1分钟

使用动态规划解决单词拆分问题

一、问题描述

给定一个非空字符串s和一个包含非空单词的列表wordDict,判定s是否可以被空格拆分为一个或多个在字典中出现的单词。

例如,给定s = "leetcode",dict = ["leet", "code"],返回true,因为"leetcode"可以被拆分为"leet"和"code"。

二、解题思路

本题可以使用动态规划来解决。具体思路如下:

  1. 定义状态

首先,我们定义一个状态f(i)表示s中前i个字符是否能被拆分成若干个字典中的单词。

  1. 初始化

我们需要将f(0)初始化为true,表示空字符串可以被拆分成一个或多个字典中的单词。

  1. 状态转移方程

接下来,我们需要考虑f(i)的转移方程。我们可以枚举s中每一个可以被拆分的位置j(j < i),如果s[j,i]是字典中的一个单词,并且f(j)为true,那么f(i)也为true,即:

f(i) = f(j) && s[j,i] ∈ wordDict

最终,我们只需要返回f(n),即s中前n个字符是否能被拆分成字典中的单词。

三、代码实现

Java代码如下:

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        int n = s.length();
        boolean[] f = new boolean[n+1];
        f[0] = true;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < i; j++) {
                if (f[j] && wordDict.contains(s.substring(j, i))) {
                    f[i] = true;
                    break;
                }
            }
        }
        return f[n];
    }
}

四、时间复杂度

本题使用了两层循环,因此时间复杂度为O(n^2),其中n为字符串s的长度。

五、总结

本题使用动态规划的思想来解决,需要定义状态、初始化和转移方程。在实现时,我们需要使用两层循环来枚举所有可能的拆分位置,并判断是否满足条件。