LeetCode.139. 单词拆分

LeetCode.139. 单词拆分

传送门

思路:1. d p dp 。设 d p [ i ] dp[i] i i 个字符的子串能否满足条件。用 s e t set 储存单词,然后枚举末尾的子串查找是否为单词。时间复杂度: O ( n 2 ) O(n^2)

2.记忆化搜索,能用 d p dp 的都能用记忆化搜索。

d p dp 代码:

class Solution {
public:
    bool wordBreak(string s, vector<string>& a) {
         unordered_set<string>se;
         for(auto i:a)
            se.insert(i);
         vector<bool>dp(s.size()+1);
         dp[0]=true;
         for(int i=1;i<=s.size();i++)
           for(int j=i-1;j>=0;j--)
            if(dp[j]&&se.find(s.substr(j,i-j))!=se.end())
            {
                dp[i]=true;
                break;
            }
        return dp[s.size()];
    }
};

剪枝的 d p dp

class Solution {
public:
    bool wordBreak(string s, vector<string>& a) {
         unordered_set<string>se;
         int mn=1e9,mx=0;
         for(auto i:a)
            se.insert(i),mn=min(mn,(int)i.size()),mx=max(mx,(int)i.size());
         vector<bool>dp(s.size()+1);
         dp[0]=true;
         for(int i=1;i<=s.size();i++)
           for(int j=max(i-mx,0);j<=i-mn;j++)
            if(dp[j]&&se.find(s.substr(j,i-j))!=se.end())
            {
                dp[i]=true;
                break;
            }
        return dp[s.size()];
    }
};

记忆化搜索:

class Solution {
public:
    unordered_set<string>se;
    bool dfs(string &s,int id,vector<int> &dp){
         if(id==0) return dp[0]=1;
         if(dp[id]!=-1) return dp[id]==1;
         for(int i=id-1;i>=0;i--){
             if(se.find(s.substr(i,id-i))!=se.end()){
                int ok=dfs(s,i,dp);
                if(ok){
                    dp[i]=1;
                    return 1;
                }
                else dp[i]=0;
             }
         }
       return 0;
    }
    bool wordBreak(string s, vector<string>& a) {
         for(auto i:a)
            se.insert(i);
        vector<int>dp(1000,-1);
         return dfs(s,s.size(),dp);
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/106960763