leetcode Word Break-单词划分

题目描述:
给定一个字符串s和一组单词,确定这个字符串是否能够进行这样一种划分,划分后所有的子字符串均来自给定的单词组。例如s = “leetcode” ,dict = {“leet”,“code”},那么s可以由dict中的单词组成。
题目来源:
http://oj.leetcode.com/problems/word-break/
题目分析:
可以将原问题的解通过解子问题来解决,用dp[i]表示字符串s从1到i是否能够进行这样的划分,假如s[1...j - 1](j - 1 < i)能够进行这样的划分并且s[j...i]是给定字典中的某个单词,那么,容易知道s[1...i]也能够进行这样的划分,计算位置 i 时,查找所有符合条件的单词,然后通过判断子问题的解来确定当前的解。通过迭代计算得到最终解。在进行字符串匹配的时候 通过Trie结构优化。使用Trie结构找到所有符合条件的单词用线性时间。
时间复杂度:O(n^2 + t*l)(n为字符串s的长度,t为字典中单词的个数,l为字典单词的平均长度)
示例代码:
struct tree_node {

    bool isstr;

    int next[branchNum];

}node[Max];



bool wordBreak(string s, unordered_set<string> &dict) {

    p = 2;

    memset(node[1].next, 0, sizeof(node[1].next));

    int n = s.length();



    unordered_set<string>::iterator it = dict.begin();

    while(it != dict.end()) {

        insertstr(*it);

        ++it;

    }



    vector<bool> dp(n + 1, false);

    int location = 1;

    for(int i = n - 1; i >= 0; --i) {

        location = 1;

        for(int j = i; j < n; ++j) {

            if(node[location].next[s[j] - 'a'] == 0)

                break;

            location = node[location].next[s[j] - 'a'];

            if(node[location].isstr) {

                if(j == n - 1)

                    dp[i] = true;

                else {

                    dp[i] = dp[i] | dp[j + 1];

                    if(dp[i])

                        break;

                }

            }

        }

    }



    return dp[0];

}



void insertstr(string t) {

    const char *word = t.c_str();

    int location = 1;



    while(*word) {

        if(node[location].next[*word - 'a'] == 0 || node[location].next[*word - 'a'] >= p) {

            node[p].isstr = false;

            memset(node[p].next, 0, sizeof(node[p].next));

            node[location].next[*word - 'a'] = p++;

        }

        location = node[location].next[*word - 'a'];

        word++;

    }

    node[location].isstr = true;

}

 

你可能感兴趣的:(LeetCode)