LeetCode每日一题 (51) 140. 单词拆分 II(记忆化搜索)

140. 单词拆分 II


在这里插入图片描述
在这里插入图片描述



超时:

class Solution {
    
    
public:
    vector<string> wordBreak(string s, vector<string>& wordDict) {
    
    
        string tempResult="";
        vector<string> result;
        choose(s,0,tempResult,result,wordDict);
        return result;
    }

    // s.substr(5, 3); 
    void choose(string s,int start,string tempResult,vector<string> &result,vector<string>& wordDict){
    
    
        if(start==s.size()){
    
    
            result.push_back(tempResult);
            return;
        }
        for(int i=start;i<s.size();i++){
    
    
            string t=s.substr(start,i-start+1);
            string oldtemp=tempResult;
            if(IsTrue(t,wordDict)){
    
    
                if(i+1>=s.size()){
    
    
                    tempResult+=t;
                }else{
    
    
                    tempResult+=t+" ";
                }
                
                choose(s,i+1,tempResult,result,wordDict);
                tempResult=oldtemp;
            }
        }
    }

    // 判断这个t字串是否在字典wordDict中
    bool IsTrue(string t,vector<string>& wordDict){
    
    
        for(int i=0;i<wordDict.size();i++){
    
    
            if(t==wordDict[i]) return true;
        }
        return false;
    }
};

在这里插入图片描述


记忆化搜索:
在这里插入图片描述

这个题目如果直接使用递归,那么就会超时,因为递归时,从i的位置开始拆分的情况会被多次重复执行,所有我们需要纪录下每一个i开始的拆分可能,方便后面递归时重复使用。

class Solution {
    
    
public:
    // 这个题目如果直接使用递归,那么就会超时,因为递归时,从i的位置开始拆分的情况会被多次重复执行,所有我们需要纪录下每一个i开始的拆分可能,方便后面递归时重复使用。


    unordered_set<string> wordSet; // 这里定义一个集合,用来后面判断单词是否存在wordDict中
    
    // result就比较重要了:result纪录每一个索引位置开始的单词拆分(多个可能)的vector
    // result[start],表示从start开始单词拆分的可能性纪录

    /****加入从start开始的第一个单词有3个字母,那么result[start]的结果为word加上result[start+3]的每一种可能
    for(const string& item:result[i+3]){
        result[start].push_back(word +item);
    }
    ****/
    unordered_map<int, vector<string>> result; // 纪录每个start开始划分的可能结果
    vector<string> wordBreak(string s, vector<string>& wordDict) {
    
    
        wordSet = unordered_set(wordDict.begin(), wordDict.end()); 
        choose(s,0); // 从0开始拆分
        return result[0];
    }
    void choose(string s,int start){
    
    
        if (result.count(start)!=0)  return;  // 如果已有纪录不需往下执行
        if(start==s.size()){
    
     // 到最后位置
            result[start]={
    
    ""};
            return;
        }
        for(int i=start;i<s.size();++i){
    
    
            string word=s.substr(start,i-start+1); // 拆分出一个单词
            if(wordSet.count(word)){
    
    
                choose(s,i+1);  // 先递归一下后面的,不然下面下面就不能正确执行
                for(const string& item:result[i+1]){
    
     // 拼接
                    if(item=="") result[start].push_back(word +item);
                    else result[start].push_back(word +" "+item);
                }
            }
        }
    }
};

在这里插入图片描述


猜你喜欢

转载自blog.csdn.net/qq_45021180/article/details/109434105