列表

详情


NC182. 单词拆分(二)

描述

给定一个字符串 s 和一个字符串数组 dic ,在字符串 s 的任意位置添加任意多个空格后得到的字符串集合是给定字符串数组 dic 的子集(即拆分后的字符串集合中的所有字符串都在 dic 数组中),你可以以任意顺序 返回所有这些可能的拆分方案

数据范围:字符串长度满足 ,数组长度满足 ,数组中字符串长度满足

示例1

输入:

"nowcoder",["now","coder","no","wcoder"]

输出:

["no wcoder","now coder"]

示例2

输入:

"nowcoder",["now","wcoder"]

输出:

[]

示例3

输入:

"nowcoder",["nowcoder"]

输出:

["nowcoder"]

示例4

输入:

"nownowcoder",["now","coder"]

输出:

["now now coder"]

说明:

你可以重复使用 dic 数组中的字符串

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 3ms, 内存消耗: 768KB, 提交时间: 2022-02-03

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param dic string字符串vector 
     * @return string字符串vector
     */
    
    bool cmp(pair<int,int> &a, pair<int,int> &b)
    {
        if(a.first < b.first)
            return true;
        else if(a.first == b.first)
        {
            if(a.second < b.second)
                return true;
            else
                return false;
        }
        else
            return false;
    }
    
    vector<string> wordDiv(string s, vector<string>& dic)
    {
        vector<string> ret;
        int maxWidth = 0;
        unordered_set<string> wordDictSet;
        
        vector<pair<int,int>> range;
        
        for (int i=0; i<dic.size(); ++i) 
        {
            wordDictSet.insert(dic[i]);
            if(dic[i].length() > maxWidth)
                maxWidth = dic[i].length();
        }
        
        //定义dp[i] 表示字符串 s 前 i 个字符组成的字符串 s[0..i-1] 
        //是否能被空格拆分成若干个字典中出现的单词
        vector<bool> dp(s.size()+1, false);
        
        dp[0] = true;
        for (int i = 1; i <= s.size(); ++i) 
            for (int j = max(i - maxWidth, 0); j <=i ; ++j) 
            {
                if (dp[j] &&
                    wordDictSet.find(s.substr(j, i-j)) != wordDictSet.end())
                {
                    dp[i] = true;
                    
                    pair<int, int> loc(j, j + i-j-1);
                    range.push_back(loc);
                    //break;
                }
            }
        if(dp[s.size()] == false) return ret;
        
        sort(range.begin(), range.end());
        
        
        vector<bool> isVisited(range.size(), false);
        
        for(int i=0; i<range.size(); ++i)
        {
           if(range[i].first == 0)
           {
               isVisited[i] = true;
               vector<string> ans;
               ans.push_back(s.substr(range[i].first, range[i].second - range[i].first + 1));
               dfs(range, i, s, ans, isVisited,ret);
           }
        }
        
        sort(ret.begin(), ret.end());
        return ret;
    }
    
    void dfs(vector<pair<int, int>> &range, int preIdx, string &s, vector<string> &ans, vector<bool> &isVisited, vector<string> &ret)
    {
        if(range[preIdx].second == s.size()-1)
        {
            string temp="";
            for(int j =0; j<ans.size()-1; ++j)
                temp += ans[j] + " ";
            temp += ans[ans.size()-1];
            ret.push_back(temp);
            return;
        }
        
        for(int i=preIdx+1; i<range.size(); ++i)
        {
            if(range[i].first == 1 + range[preIdx].second)
            {
                isVisited[i] = true;
                ans.push_back(s.substr(range[i].first, range[i].second-range[i].first + 1));
                dfs(range, i, s, ans, isVisited, ret);
                isVisited[i] = false;
                ans.pop_back();
            }
            else if(range[i].first > 1 + range[preIdx].second)
                break;
        }
    }
};
class Solution4 {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param dic string字符串vector 
     * @return string字符串vector
     */
    
    bool cmp(pair<int,int> &a, pair<int,int> &b)
    {
        if(a.first < b.first)
            return true;
        else if(a.first == b.first)
        {
            if(a.second < b.second)
                return true;
            else
                return false;
        }
        else
            return false;
    }
    
    vector<string> wordDiv(string s, vector<string>& dic)
    {
        vector<string> ret;
        int maxWidth = 0;
        unordered_set<string> wordDictSet;
        
        vector<pair<int,int>> range;
        
        for (int i=0; i<dic.size(); ++i) 
        {
            wordDictSet.insert(dic[i]);
            if(dic[i].length() > maxWidth)
                maxWidth = dic[i].length();
        }
        
        //定义dp[i] 表示字符串 s 前 i 个字符组成的字符串 s[0..i-1] 
        //是否能被空格拆分成若干个字典中出现的单词
        vector<bool> dp(s.size()+1, false);
        
        dp[0] = true;
        for (int i = 1; i <= s.size(); ++i) 
            for (int j = max(i - maxWidth, 0); j <=i ; ++j) 
            {
                if (dp[j] &&
                    wordDictSet.find(s.substr(j, i-j)) != wordDictSet.end())
                {
                    dp[i] = true;
                    
                    pair<int, int> loc(j, j + i-j-1);
                    range.push_back(loc);
                    //break;
                }
            }
        if(dp[s.size()] == false) return ret;
        
        sort(range.begin(), range.end());
        
        
        vector<bool> isVisited(range.size(), false);
        
        for(int i=0; i<range.size(); ++i)
        {
            if(range[i].first != 0) break;
            int preIdx = i;
            string first_str= s.substr(range[i].first, range[i].second - range[i].first + 1);
            string nxt_str= "";
            for(int j = i+1; j < range.size() && range[preIdx].second != s.size() - 1; ++j)
            {
                if(range[j].first == range[preIdx].second + 1)
                {
                    preIdx = j;
                    if(range[j].second != s.size()-1)
                        nxt_str += s.substr(range[j].first, range[j].second - range[j].first + 1) + " ";
                    else
                        break;
                }
            }
            if(preIdx != i)
            {
                nxt_str += s.substr(range[preIdx].first, range[preIdx].second - range[preIdx].first + 1);
                first_str += " " + nxt_str;
            }

            ret.push_back(first_str);
        }
        
        sort(ret.begin(), ret.end());
        return ret;
    }
};

C++ 解法, 执行用时: 4ms, 内存消耗: 1032KB, 提交时间: 2021-11-25

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param dic string字符串vector 
     * @return string字符串vector
     */
    vector<string> wordDiv(string s, vector<string>& dic) {
        int size=s.size();
        poslst.resize(size);
        int dicsize=dic.size();
        unordered_set<string> repeatchk;
        for(int i=0;i<dicsize;++i) {
            if(repeatchk.count(dic[i])==0) {
                repeatchk.insert(dic[i]);
                kmp(dic[i], s);
            }
        }
        
        for(int i=0;i<poslst.size();++i) {
            vector<int> &pos=poslst[i];
            sort(pos.begin(), pos.end());
        }
        
        cat(0, size);
        
        int lstsize=answerlst.size();
        vector<string> result(lstsize);
        for(int i=0;i<lstsize;++i) {
            string &str=result[i];
            vector<int> &ans=answerlst[i];
            int anssize=ans.size();
            str.reserve(size+anssize+1);
            str=s.substr(0, ans[0]);
            for(int j=1;j<anssize;++j) {
                str.push_back(' ');
                str.append(s.substr(ans[j-1], ans[j]-ans[j-1]));
            }
        }
        
        return result;
    }
private:
    vector<vector<int>> poslst;
    vector<vector<int>> answerlst;
    vector<int> answer;
    void cat(int start, int size) {
        if(start==size) {
            answerlst.push_back(answer);
            return;
        }
        
        vector<int> &lst=poslst[start];
        for(int i=0;i<lst.size();++i) {
            answer.push_back(lst[i]);
            cat(lst[i], size);
            answer.pop_back();
        }
    }
    
    void kmp(string S, string T) {
        int Ssize=S.size();
        int Tsize=T.size();
        vector<int> next(Ssize+1, 0);
        genNext(S, next);
        int i=0;
        int j=0;
        while(i<Tsize) {
            if(j==-1 || S[j]==T[i]) {
                ++i;
                ++j;
            }
            else {
                j=next[j];
            }
            if(j==Ssize) {
                j=next[j];
                poslst[i-Ssize].push_back(i);
            }
        }
        
    }
    
    void genNext(string &s, vector<int> &next) {
        int size=s.size();
        next[0]=-1;
        int i=0;
        int k=-1;
        while(i<size) {
            if(k==-1 || s[i]==s[k]) {
                ++i;
                ++k;
                next[i]=(s[i]==s[k] ? next[k] : k);
            }
            else {
                k=next[k];
            }
        }
    }
};

C++ 解法, 执行用时: 4ms, 内存消耗: 1048KB, 提交时间: 2022-02-04

class Solution {
public:
    unordered_map<string,int> mp;
    int len;
    vector<string> res;
    
    vector<string> wordDiv(string s, vector<string>& dic) {
        int n=dic.size();
        len=s.size();
        for(int i=0;i<n;i++){
            mp[dic[i]]=1;
        }
        dfs(s,0,"");
        return res;
    }
    
    void dfs(string s,int st,string str){
        if(len==st){
            res.push_back(str.substr(0,str.size()-1));
            return;
        }
        string x="";
        for(int i=st;i<len;i++){
            x+=s[i];
            if(mp.count(x)){
                dfs(s,i+1,str+x+" ");
            }
        }
    }
};

C++ 解法, 执行用时: 4ms, 内存消耗: 1060KB, 提交时间: 2022-01-04

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param dic string字符串vector 
     * @return string字符串vector
     */
    struct treeNode {
        string word;
        vector<treeNode*> next;
    };
    vector<string >res;
    // 写的太慢 隐藏的题意 可以重复使用字符串
    void sub(string s, int idx, string cur, treeNode* root){
        if (idx == s.size()) res.push_back(cur);
        treeNode* curRoot = root;    
        for(int i = idx; i < s.size(); i++){
            if (i < s.size() && curRoot->next[s[i]-'a'] != NULL) {
               curRoot = curRoot->next[s[i]-'a'];
            }else return ;
            if (curRoot->word != ""){
                string next = cur + " " + curRoot->word;
                if (cur == "") next = curRoot->word;
                sub(s, i+1, next, root);
            }
            
        }
        return;
    }
    vector<string> wordDiv(string s, vector<string>& dic) {
        // write code here
        
        // dict用字典树重新
        treeNode* root = new treeNode();
        root->next.resize(26);
        for(int i = 0; i < dic.size(); i++){
            string cur = dic[i];
            treeNode* temp = root;
            for(int j = 0; j < cur.size(); j++){
                if (temp->next[cur[j]-'a'] == NULL){
                    treeNode* c = new treeNode();
                    c->next.resize(26);
                    temp->next[cur[j]-'a'] = c;
                }
                temp = temp->next[cur[j] - 'a'];
            }
            temp->word = cur;
        }
        string buf = "";
        sub(s, 0, buf, root);
        //sort(res.begin(), res.end());
        return res;
        
    }
};

C++ 解法, 执行用时: 4ms, 内存消耗: 1064KB, 提交时间: 2022-02-10

class Solution {
public:
    vector<string> str_vec;
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param dic string字符串vector 
     * @return string字符串vector
     */
    vector<string> wordDiv(string s, vector<string>& dic) {
        // write code here
        int len_s = s.length();
        assert(len_s && len_s<=20);
        
        str_vec = vector<string>();
        
        unordered_map<char, unordered_set<string>> ch_str_unset_unmap;
        for(string &str : dic){
            assert(!str.empty() && str.length()<=20);
            ch_str_unset_unmap[ str[0] ].insert(str);
        }
        if( !ch_str_unset_unmap.count( s[0] ) ) return {};
        
        for(const string &str : ch_str_unset_unmap[ s[0] ]){
            int len_str = str.length();
            if(len_str > len_s) continue;
            int idx = 0;
            while(idx<len_str && str[idx]==s[idx])
                ++idx;
            if(idx == len_str) DFS(ch_str_unset_unmap, s, len_s, len_str, str);
        }
        sort(str_vec.begin(), str_vec.end());
        return str_vec;
    }
    
    void DFS(unordered_map<char, unordered_set<string>> &ch_str_unset_unmap, 
            string &s, const int len_s, int next_idx, string cur_str)
    {
        if(next_idx < len_s){
            for(const string &str : ch_str_unset_unmap[ s[next_idx] ]){
                int len_str = str.length();
                if(next_idx+len_str > len_s) continue;
                int idx = 0;
                while(idx<len_str && str[idx]==s[ next_idx+idx ])
                    ++idx;
                if(idx == len_str) DFS(ch_str_unset_unmap, s, len_s, next_idx+len_str, cur_str+' '+str);
            }
        }
        else str_vec.push_back(cur_str);
    }
};

上一题