【LeetCode-139】单词拆分

问题

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

说明:

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

示例

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

解答

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> ust(wordDict.begin(), wordDict.end());
        int n = s.size(), minLen = INT_MAX, maxLen = 0;
        vector<int> dp(n + 1);
        dp[0] = 1;
        for (string& w : wordDict) { // 用于剪枝
            minLen = min(minLen, (int)w.size());
            maxLen = max(maxLen, (int)w.size());
        }
        for (int i = minLen; i <= n; i++) {
            for (int j = max(0, i - maxLen); j <= i - minLen; j++) {
                if (ust.count(s.substr(j, i - j)) && dp[j]) {
                    dp[i] = 1;
                    break;
                }
            }
        }
        return dp[n];
    }
};

重点思路

本题可以看做一道完全背包问题,也就是字典中元素为物品,s为背包。但是我觉得这道题看做字符串的动态规划比较直观。dp[i]表示从角标0出发,以角标i结尾的字符串是否能被字典中的单词拆分。本题做了剪枝操作,提升效果较为明显,从24ms提升至0ms。

posted @ 2021-04-02 17:31  tmpUser  阅读(56)  评论(0编辑  收藏  举报