鱼C论坛

 找回密码
 立即注册
查看: 1047|回复: 0

[技术交流] C++刷leetcode(472. 连接词)【字典树】

[复制链接]
发表于 2020-4-12 15:26:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 糖逗 于 2020-4-12 15:41 编辑

题目描述:
给定一个不含重复单词的列表,编写一个程序,返回给定单词列表中所有的连接词。

连接词的定义为:一个字符串完全是由至少两个给定数组中的单词组成的。

示例:

输入: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"]

输出: ["catsdogcats","dogcatsdog","ratcatdogcat"]

解释: "catsdogcats"由"cats", "dog" 和 "cats"组成; 
     "dogcatsdog"由"dog", "cats"和"dog"组成; 
     "ratcatdogcat"由"rat", "cat", "dog"和"cat"组成。
说明:

给定数组的元素总数不超过 10000。
给定数组中元素的长度总和不超过 600000。
所有输入字符串只包含小写字母。
不需要考虑答案输出的顺序。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/concatenated-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


#include <iostream>
#include <string>
#include <vector>
#include <map>

using namespace std;


struct TrieNode{
        bool flag;
        map<char, TrieNode*> next;
        TrieNode():flag(false){
                
        }
};

TrieNode* root = new TrieNode();
void init(vector<string> & input){
        for(auto word : input){
                TrieNode* temp = root;
                for(auto cha:word){
                        if(temp -> next.count(cha) == 0){
                                temp-> next[cha] = new TrieNode();
                        }
                        temp = temp ->next[cha];
                        
                }
                temp -> flag = true;
        }
        
}



bool valid(string input){
        
        int len = input.size();
        vector<vector<int> > dp(len + 1);
        dp[0] = vector<int>(1, -1);
        for(int i = 0; i < len; i++){
                if(dp[i].empty() || root-> next.count(input[i]) == 0) continue;
                TrieNode* temp = root;
                int j = i;
                while(j < len && temp -> next.count(input[j])){
                        temp = temp -> next[input[j++]];
                        if(temp -> flag){
                                if(i != 0 && j == len) return true;
                                dp[j].push_back(i); 
                        }
                }
        }
        return false;
        
}

vector<string> solution(vector<string>&input){
        vector<string> res;
        init(input);
        for(auto word : input){
                if(valid(word)){
                        res.push_back(word);
                }
        }
        return res;
}




int main(void){
        vector<string> input;
        string words;
        while(cin >> words){
                input.push_back(words);
        }
        
        vector<string> res = solution(input);
        for(int i = 0; i < res.size(); i++){
                cout << res[i] << " ";
        } 
        cout << endl;
        return 0;
}


注意事项:
1.参考链接:https://leetcode-cn.com/problems ... -hua-by-da-li-wang/
2.dp是作为动态规划的中间存储,先构建字典树。
3.i != 0的判断是保证长字符串中至少有两个子串。
4.字典树的参考链接:https://blog.csdn.net/bqw18744018044/article/details/82502435

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-15 06:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表