1. 程式人生 > 其它 >LeetCode/單詞拆分

LeetCode/單詞拆分

給你一個字串 s 和一個字串列表 wordDict 作為字典。請你判斷是否可以利用字典中出現的單詞拼接出 s 。
注意:不要求字典中出現的單詞全部都使用,並且字典中的單詞可以重複使用。

思路:對於是否可行問題考慮用回溯法,遞迴s串中的下標,同時遍歷可選字典陣列,進行匹配,匹配失敗選擇其他項,防止無限遞迴
當資料規模變大後,回溯法執行超時

回溯法
class Solution {
public:
    bool flag = false;
    bool wordBreak(string s, vector<string>& wordDict) {
        //每個滿足條件的單詞都應該進行匹配
        //判斷可行考慮用回溯法
        backtrack(s,wordDict,0);
        return flag;
    }

    void backtrack(string s,vector<string>& wordDict,int index){
        if(index==s.size()){flag=true;return;}
        int start = index;
        for(int i=0;i<wordDict.size();i++){
            index = compare(s,wordDict[i],index);
            if(index==start) continue;
            backtrack(s,wordDict,index);
            if(flag) return;
            index = start;
        }
    }

    int compare(string s,string wordDict,int index){
        int start = index;
        for(int j=0;j<wordDict.size();j++){
            if(index>s.size()-1||s[index]!=wordDict[j]) return start;
            index++;
        }
        return index;
}
};

動態規劃

dp[i]表示為前i個字元組成的串匹配成功的可行性
邊界條件:dp[0]=true;
狀態轉移方程:dp[i]=dp[j]&&(j-i字串在字典中)//j遍歷i前面全部位置

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> wordDictSet(wordDict.begin(), wordDict.end());//雜湊表判斷匹配
        vector <bool> dp(s.size() + 1);
        dp[0] = true;
        for (int i = 1; i <= s.size(); ++i) {//評估前i位字串是否能匹配成功
            for (int j = 0; j < i; ++j) {//判斷前j位是否匹配成功,以及j到i之間字串是否存在匹配項
                if (dp[j] && wordDictSet.count(s.substr(j, i - j)) ) {
                    dp[i] = true;
                    break;
                }
            }
        }

        return dp[s.size()];
    }
};