LeetCode7.10恢复空格 (字典树)

LeetCode7.10恢复空格 (字典树)_第1张图片
最开始的思路是所有字符串匹配,但有逻辑错误,因为可能字典里的单词有相同的前缀和后缀。
错误代码,能通过部分样例

class Solution {
public:
    int respace(vector<string>& dictionary, string sentence) {
        int falg = false;
        int ci = 0;
        vector <string> dict[26];
        for(int i = 0; i < dictionary.size(); i++) {
            dict[dictionary[i][0]-'a'].push_back(dictionary[i]);
        }
        for(int i  = 0 ; i < sentence.size(); i++){
            int ch = sentence[i] - 'a';
            falg = false;
            for(int j = 0; j < dict[ch].size();j++){
                if(i+dict[ch][j].size() <= sentence.size() && sentence.substr(i,dict[ch][j].size()) == dict[ch][j]){
                    i += dict[ch][j].size();
                    falg = true;
                    break;
                }
            }
        if(falg) i--;
         else ci++;
        }
        return ci;
    }
    
};

看了官方的题解,了解了一种新的数据结构---------字典树,单词树,字符串树
LeetCode7.10恢复空格 (字典树)_第2张图片
字典树的三个特性:
根节点不包含字符,除根节点外每一个节点都只包含一个字符
从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
每个节点的所有子节点包含的字符都不相同

该题目用的字典树是逆序字典树
LeetCode7.10恢复空格 (字典树)_第3张图片
just like looked brother
状态转移方程:
LeetCode7.10恢复空格 (字典树)_第4张图片
每次isEnd 为真时改变一次转态,但要继续搜索下去(考虑相同后缀)

class Trie {
public:
    Trie* next[26] = {nullptr};
    bool isEnd;
    
    Trie() {
        isEnd = false;
    }

    void insert(string s) {
        Trie* curPos = this;

        for (int i = s.length() - 1; i >= 0; --i) {
            int t = s[i] - 'a';
            if (curPos->next[t] == nullptr) {
                curPos->next[t] = new Trie();
            }
            curPos = curPos->next[t];
        }
        curPos->isEnd = true;
    }
};

class Solution {
public:
    int respace(vector<string>& dictionary, string sentence) {
        int n = sentence.length(), inf = 0x3f3f3f3f;

        Trie* root = new Trie();
        for (auto& word: dictionary) {
            root->insert(word);
        }

        vector<int> dp(n + 1, inf);
        dp[0] = 0;
        for (int i = 1; i <= n; ++i) {
            dp[i] = dp[i - 1] + 1;

            Trie* curPos = root;
            for (int j = i; j >= 1; --j) {
                int t = sentence[j - 1] - 'a';
                if (curPos->next[t] == nullptr) {
                    break;
                } else if (curPos->next[t]->isEnd) {
                    dp[i] = min(dp[i], dp[j - 1]);
                }
                if (dp[i] == 0) {
                    break;
                }
                curPos = curPos->next[t];
            }
        }
        return dp[n];
    }
};

你可能感兴趣的:(Leetcode,C/C++)