动态规划之单词拆分

题目描述

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

说明:

拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。

示例

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。
示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
     注意你可以重复使用字典中的单词。
示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

题目分析

  • 状态: 拆分字符串s的位置j
  • 选择:wordDict中的哪个字符可以匹配s[i:j]
  • dp数组定义:dp[i]表示s中前i个字符是否可以被拆分
  • 状态转移方程:
如果s中前j个字符可以被拆分且s中j到i可在wordDict中找到
则s中前i个字符都可以被拆分
dp[i] = dp[j] + s[j:i] in wordDict
- 边界条件:s的前0个字符,即s为空的时候无为而治即可拆分s.

代码(C++)

bool wordBreak(string s, vector<string>& wordDict) {
        int n = s.size();
        vector<bool>dp(n+1,false);
        dp[0] = true;
        for (int i=0; i<n+1; i++){
            for (int j=0; j<i; j++){
                if (dp[j] && find(wordDict.begin(), wordDict.end(), s.substr(j,i-j))!= wordDict.end())
                {
                    dp[i] = true;
                    break;
                }
            }
        }
    return dp[n];
    }

时间复杂度:O(n^2),空间复杂度O(n)
代码(python3)

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        n = len(s)
        dp = [False for _ in range(n+1)]
        dp[0] = True
        for i in range(n+1):
            for j in range(i):
                if dp[j] and s[j:i] in wordDict:
                    dp[i] = True
                    break
        return dp[-1]
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。