MyTrie结构体和相关操作函数

typedef struct MyTrie {bool is_word;vector<MyTrie*> next;MyTrie():is_word(false) {next.resize(26,nullptr);}
}MT;
void insertWord(MT* cur, const string& word) {for (auto &w:word) {int c = w - 'a';if (!cur->next[c]) {auto tmp = new MT();cur->next[c] = tmp;}cur = cur->next[c];}cur->is_word = true;
}
bool hasWord(MT* cur, const string& word) {for (auto &w: word) {int c = w - 'a';if (!cur->next[c]) return false;cur = cur->next[c];}return cur->is_word;
}
vector<string> findChangeNeighbor(MT* cur, const string& word) {            // 127. 单词接龙vector<string> res;for (int i = 0; i < word.size(); ++i) {int c = word[i] - 'a';for (int j = 0; j < 26; ++j) {if (c == j) continue;if (cur->next[c] && hasWord(cur->next[c], word.substr(i + 1))) {auto tmp = word;tmp[i] = j + 'a';res.push_back(move(tmp));}}cur = cur->next[c];}return res;
}
bool isEveryStepWord(MT* cur, const string& word) {             for (auto &w: word) {int c = w - 'a';if (!cur->next[c] || !cur->next[c]->is_word) return false;}return true;
}
int getEverySetpWordMaxLength(MT* cur, const string& word) {int max_length = -1;queue<MT*>q;q.push(cur);while (q.size()) {auto qs = q.size();++max_length;while (qs--) {auto tmp = q.front();q.pop();for (auto &i: tmp->next) {if (i && i->is_word) {q.push(i);}}}}return max_length;
}
void findMaxLengthWordWithDFS(MT* cur, string& res_string, string path) {   // 720. 词典中最长的单词if (path.size() > res_string.size()) {res_string = path;}    for (int i = 0; i < 26; ++i) {auto w = cur->next[i];if (!w || !w->is_word) continue;findMaxLengthWordWithDFS(w, res_string, path + static_cast<char>(i + 'a'));}
}
vector<string> findWordStartWithPrefix(MT* cur, const string& prefix) {     // 677. 键值映射vector<string> res;for (int i = 0; i < prefix.size(); ++i) {int c = prefix[i] - 'a';if (!cur->next[c]) return {};cur = cur->next[c];}queue<pair<MT*, string>> q;q.push(make_pair(cur, prefix));while (q.size()) {auto qs = q.size();while (qs--) {auto [le, ri] = q.front();q.pop();if (le->is_word) res.push_back(ri);for (int i = 0; i < 26; ++i) {if (!le->next[i]) continue;q.push(make_pair(le->next[i], ri + static_cast<char>(i + 'a')));}}}return res;
}
void findEveryWordPosition(MT* cur, const string& target,                   // 面试题 17.17. 多次搜索vector<vector<int>>& res_pos,unordered_map<string, int>& word_to_id) {for (int i = 0; i < target.size(); ++i) {           // i:pos_startint cur_i =target[i] - 'a';if (!cur->next[cur_i]) continue;auto cur_sub = cur->next[cur_i];for (int j = i + 1; j <= target.size(); ++j) {  // j:pos_end          if (cur_sub->is_word) {res_pos[word_to_id[target.substr(i, j - i)]].push_back(i);}if (j == target.size()) break;int cur_sub_i = target[j] - 'a';if (!cur_sub->next[cur_sub_i]) break;cur_sub = cur_sub->next[cur_sub_i];}}
}
string findMinPrefix(MT* cur, const string& word) {                          // 648. 单词替换string min_prefix;for (auto &w: word) {int c = w - 'a';if (!cur->next[c]) return word;min_prefix += w;if (cur->next[c]->is_word) return min_prefix;cur = cur->next[c];}return min_prefix;
}

给出一个字符串数组words组成的一本英语词典。从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。

若无答案,则返回空字符串。

示例 1:

输入:
words = ["w","wo","wor","worl", "world"]
输出:"world"
解释: 
单词"world"可由"w", "wo", "wor", 和 "worl"添加一个字母组成。

示例 2:

输入:
words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
输出:"apple"
解释:
"apply"和"apple"都能由词典中的单词组成。但是"apple"的字典序小于"apply"。

提示:

所有输入的字符串都只包含小写字母。
    words数组长度范围为[1,1000]。
    words[i]的长度范围为[1,30]。

class Solution {
public:string longestWord(vector<string>& words) {auto mt = new MT();for (auto &w: words)insertWord(mt, w);string res_string;findMaxLengthWordWithDFS(mt, res_string, "");return res_string;}
};

给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:

每次转换只能改变一个字母。
    转换过程中的中间单词必须是字典中的单词。

说明:

如果不存在这样的转换序列,返回 0。
    所有单词具有相同的长度。
    所有单词只由小写字母组成。
    字典中不存在重复的单词。
    你可以假设 beginWord 和 endWord 是非空的,且二者不相同。

示例 1:

输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出: 5

解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
     返回它的长度 5。

示例 2:

输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

输出: 0

解释: endWord "cog" 不在字典中,所以无法进行转换。

class Solution {
public:int ladderLength(string beginWord, string endWord, vector<string>& wordList) {if (beginWord.size() == 0 || beginWord.size() != endWord.size()) return 0;int min_cnt = 1;MyTire *allWord = new MyTire(), *visited = new MyTire();insertWord(allWord, beginWord);for (int i = 0; i<wordList.size(); ++i)insertWord(allWord, wordList[i]);if (!hasWord(allWord, endWord)) return 0;queue<string> q;q.push(beginWord);while (q.size()) {int qSize = q.size();++min_cnt;while (qSize--) {auto cur = q.front();q.pop();vector<string> vec = findChangeNeighber(allWord, cur);for (int i = 0; i<vec.size(); ++i) {if (hasWord(visited, vec[i])) continue;if (vec[i] == endWord) return min_cnt;q.push(vec[i]);insertWord(visited, vec[i]);}}}return 0;}
};

实现一个 MapSum 类里的两个方法,insert 和 sum。

对于方法 insert,你将得到一对(字符串,整数)的键值对。字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。

对于方法 sum,你将得到一个表示前缀的字符串,你需要返回所有以该前缀开头的键的值的总和。

示例 1:

输入: insert("apple", 3), 输出: Null
输入: sum("ap"), 输出: 3
输入: insert("app", 2), 输出: Null
输入: sum("ap"), 输出: 5

class MapSum {unordered_map<string, int> m;MT *mt;
public:/** Initialize your data structure here. */MapSum() {mt = new MT();}    void insert(string key, int val) {m[key] = val;insertWord(mt, key);}    int sum(string prefix) {auto vec = findWordStartWithPrefix(mt, prefix);int res_sum = 0;for (auto &v: vec) {res_sum += m[v];}return res_sum;}
};

给定一个较长字符串big和一个包含较短字符串的数组smalls,设计一个方法,根据smalls中的每一个较短字符串,对big进行搜索。输出smalls中的字符串在big里出现的所有位置positions,其中positions[i]为smalls[i]出现的所有位置。

示例:

输入:
big = "mississippi"
smalls = ["is","ppi","hi","sis","i","ssippi"]
输出: [[1,4],[8],[],[3],[1,4,7,10],[5]]

提示:

0 <= len(big) <= 1000
    0 <= len(smalls[i]) <= 1000
    smalls的总字符数不会超过 100000。
    你可以认为smalls中没有重复字符串。
    所有出现的字符均为英文小写字母。

class Solution {
public:vector<vector<int>> multiSearch(string big, vector<string>& smalls) {vector<vector<int>> res_vec(smalls.size());if (big.empty() || smalls.empty()) return res_vec;        unordered_map<string, int> word_to_id;auto mt = new MT();for (int i = 0; i < smalls.size(); ++i) {word_to_id[smalls[i]] = i;insertWord(mt, smalls[i]);}findEveryWordPosition(mt, big, res_vec, word_to_id);return res_vec;}
};

在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。

现在,给定一个由许多词根组成的词典和一个句子。你需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。

你需要输出替换之后的句子。

示例:

输入:dict(词典) = ["cat", "bat", "rat"] sentence(句子) = "the cattle was rattled by the battery"
输出:"the cat was rat by the bat"

提示:

输入只包含小写字母。
    1 <= dict.length <= 1000
    1 <= dict[i].length <= 100
    1 <= 句中词语数 <= 1000
    1 <= 句中词语长度 <= 1000

class Solution {
public:string replaceWords(vector<string>& dictionary, string sentence) {auto mt = new MT();for (auto &d: dictionary) {insertWord(mt, d);}stringstream ss(sentence);string res_string, s;while (getline(ss, s, ' ')) {res_string += findMinPrefix(mt, s) + ' ';}res_string.pop_back();return res_string;}
};

字典树/Trie/前缀树-LeetCode总结:720词典中最长的单词;127. 单词接龙;677. 键值映射;面试题 17.17. 多次搜索;648. 单词替换相关推荐

  1. 【LeetCode】720. 词典中最长的单词 【前缀树】

    题目链接:https://leetcode-cn.com/problems/longest-word-in-dictionary/ 题目描述 给出一个字符串数组words组成的一本英语词典.从中找出最 ...

  2. 720. 词典中最长的单词

    链接:720. 词典中最长的单词 题解: class Solution { private:struct Trie {int end;std::set<std::string> words ...

  3. 每日一练 LeetCode:E720. 词典中最长的单词

    题目 给出一个字符串数组 words 组成的一本英语词典.返回 words 中最长的一个单词,该单词是由 words 词典中其他单词逐步添加一个字母组成. 若其中有多个可行的答案,则返回答案中字典序最 ...

  4. leetcode 677. Map Sum Pairs | 677. 键值映射(Trie前缀树,BFS)

    题目 https://leetcode.com/problems/map-sum-pairs/ 题解 基于前缀树实现,可以参考:leetcode 208. Implement Trie (Prefix ...

  5. LeetCode 720. 词典中最长的单词(Trie树)

    1. 题目 给出一个字符串数组words组成的一本英语词典.从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成.若其中有多个可行的答案,则返回答案中字典序最小的单词. 若无 ...

  6. 720 词典中最长的单词(Trie树)

    1. 问题描述: 给出一个字符串数组words组成的一本英语词典.从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成.若其中有多个可行的答案,则返回答案中字典序最小的单词. ...

  7. LeetCode 720. 词典中最长的单词

    目录结构 1.题目 2.题解 1.题目 给出一个字符串数组words组成的一本英语词典.从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成.若其中有多个可行的答案,则返回答 ...

  8. leetcode 720. Longest Word in Dictionary | 720. 词典中最长的单词(Trie前缀树)

    题目 https://leetcode.com/problems/longest-word-in-dictionary/ 题解 建立一个 Trie,在 insert 的过程中,除最后一个节点外,如果一 ...

  9. 2022-1-22 Leetcode 720.词典中最长的单词

    这个方法对于数据量小的可行,大量的数据不可行 class Solution {public:string longestWord(vector<string>& words) {s ...

最新文章

  1. JAVA方法中的参数用final来修饰的效果
  2. webservice(基础)
  3. golang学习笔记:Interface类型断言详情
  4. war包部署-配置入口类
  5. php 取得文件行数,PHP获取文件行数的方法
  6. 移动端上下拖动调整顺序效果_HTML5 移动端的上下左右滑动问题
  7. 关于python中字典描述正确的是_python总结七
  8. shapefile(.shp)空间数据格式详细说明
  9. Kotlin 的静态代码分析工具
  10. php电子病历毕业设计,基于区块链的电子病历系统设计与实现(自制毕设)
  11. python大小写转换_Python字母大小写的转换(两种方法)
  12. 网络质量监控 - 守好入口第一关
  13. EasyExcel动态导出-动态头
  14. C# 以MP3的格式将录制的音频数据写入文件流
  15. Spring Boot拦截器(Interceptor)详解
  16. 1M带宽、1Mbps、1Mb/s 区分
  17. 人人网回归了!历史记录全保留!前任们的黑历史就要被重新翻开了
  18. SpringBoot定时任务简单应用
  19. 通达信行情接口源代码是什么?
  20. 【转】16GB大内存该怎么玩儿?

热门文章

  1. .NET 20周年软件趋势随想
  2. vscode 快速生层vue模板
  3. 网络偷窥者很多,如何消除上网的浏览痕迹?
  4. 基于Java+MySQL实现(Web)高校资源综合发布系统【100010343】
  5. 【UVM基础】TLM常用数据接发送与数据接收实例
  6. [典故收集]氪金狗眼
  7. 小傻蛋的妹妹跟随小甲鱼学习Python的第六节006
  8. OpenStack云撑起百联O2O战略布局
  9. paypal tp 对接_php对接“paypal/Checkout-PHP-SDK“支付流程
  10. testng单元测试-diagnose依赖compet找不到compet的类