[经典面试题][百度]寻找兄弟单词
来源:互联网 发布:mac下载汉仪颜体 编辑:程序博客网 时间:2024/06/02 15:31
题目
一个单词单词字母交换,可得另一个单词,如army->mary,成为兄弟单词。提供一个单词,在字典中找到它的兄弟。描述数据结构和查询过程。
思路一
兄弟单词必须满足字符相同,相同字符个数也必须相同。基于这点用Hash实现:
(1)申请一个int数组 count[26]用来统计每个字符出现的次数。
(2)扫描字典中的单词,只考虑长度和给出单词长度一样大小的单词(长度不同肯定不是兄弟单词),用broCount[26]来统计单词中每个字符出现的次数。
(3)如果count和broCount一样,表示是兄弟单词否则不是。
代码一
/*--------------------------------------------- * 日期:2015-02-22 * 作者:SJF0115 * 题目: 兄弟单词 * 来源:百度 * 博客: -----------------------------------------------*/ #include <iostream> #include <vector> #include <cstring> #include <algorithm> using namespace std; class Solution { public: // dic字典集合 word查找单词 vector<string> BrotherWord(vector<string> dic,string word){ int count[26]; vector<string> brother; // 初始化 memset(count,0,sizeof(count)); int wordSize = word.size(); int dicSize = dic.size(); // 统计字符以及个数 for(int i = 0;i < wordSize;++i){ ++count[word[i]-'a']; }//for // 遍历字典 for(int i = 0;i < dicSize;++i){ if(IsBrother(word,count,dic[i])){ brother.push_back(dic[i]); }//if }//for return brother; } private: bool IsBrother(string word,int count[],string broWord){ int size = broWord.size(); int wordSize = word.size(); // 长度不一样肯定不是兄弟单词 if(size != wordSize){ return false; }//if // 统计字符及个数 int broCount[26]; memset(broCount,0,sizeof(broCount)); for(int i = 0;i < size;++i){ ++broCount[broWord[i]-'a']; }//for // 只有字符一样,字符个数一样才是兄弟单词 int k; for(k = 0;k < 26;++k){ // 不是兄弟单词 if(count[k] != broCount[k]){ break; }//if }//for if(k == 26){ return true; }//if return false; } }; int main() { Solution solution; vector<string> dic = {"mary","many","book","army","mood","man","doom","mod"}; string word("mary"); vector<string> result = solution.BrotherWord(dic,word); for(int i = 0;i < result.size();++i){ cout<<result[i]<<" "; }//for cout<<endl; }
思路二:
在字典树的中再存储一个vector结构的容器来储存兄弟单词。
struct TrieNode{ TrieNode *next[MAX]; vector<string> brother; TrieNode(){ for(int i = 0;i < MAX;++i){ next[i] = NULL; }//for } };
字典树的建立是在预处理阶段完成的,首先根据字典中的单词来建立字典树,建立的时候,需要稍微特殊处理一下,就是比如mary、army互为兄弟单词,如果先插入单词mary,首先对其进行排序,结果是amry,那么字典树中就分别建立4个节点,分别为a->m->r->y,在节点y处的vector容器brother中添加单词mary,插入army的时候,同样的原理,先排序,再插入,此时发现这4个节点已经建立了,那么只需要在第四个节点y处的vector容器brother中添加单词army。
这样建立完字典树后,查询兄弟单词的效率就会很高了,比哈希的效率还要高;查询army的兄弟单词时,先排序(amry),然后在字典树中查找amry,在y处vector容器brother中的的单词就是所有兄弟单词。
代码二
/*--------------------------------------------- * 日期:2015-02-23 * 作者:SJF0115 * 题目: 兄弟单词 * 来源:百度 * 博客: -----------------------------------------------*/ #include <iostream> #include <vector> #include <cstring> #include <algorithm> using namespace std; #define MAX 26 struct TrieNode{ TrieNode *next[MAX]; vector<string> brother; TrieNode(){ for(int i = 0;i < MAX;++i){ next[i] = NULL; }//for } }; // 插入 void Insert(TrieNode* &root,string str){ int size = str.size(); TrieNode *p = root; string tmp = str; // 排序 sort(tmp.begin(),tmp.end()); // 插入 int val; for(int i = 0;i < size;++i){ val = tmp[i] - 'a'; if(p->next[val] == NULL){ p->next[val] = new TrieNode(); }//if p = p->next[val]; }//for p->brother.push_back(str); } // 预处理 void Init(vector<string> dic,TrieNode* &root){ int dicSize = dic.size(); if(dicSize <= 0){ return; }//if // 创建字典树 for(int i = 0;i < dicSize;++i){ Insert(root,dic[i]); }//for } // 打印字典 void PrintDic(TrieNode* root){ if(root == NULL){ return; }//if if(root->brother.size() > 0){ for(int i = 0; i < root->brother.size();++i){ cout<<root->brother[i]<<" "; }//for cout<<endl; }//if for(int i = 0;i < 26;++i){ PrintDic(root->next[i]); }//for } // 兄弟单词 vector<string> BrotherWord(TrieNode *root,string word){ int size = word.size(); vector<string> brother; if(root == NULL || size <= 0){ return brother; }//if // 排序 sort(word.begin(),word.end()); TrieNode *p = root; int val; for(int i = 0;i < size;++i){ val = word[i] - 'a'; if(p->next[val] == NULL){ return brother; }//if p = p->next[val]; }//for return p->brother; } int main() { vector<string> dic = {"mary","many","book","army","mood","mray","man","doom","mod"}; string word("mod"); TrieNode *root = new TrieNode(); // 预处理 创建字典树 Init(dic,root); // 查询兄弟单词 vector<string> result = BrotherWord(root,word); if(result.size() <= 0){ cout<<"单词["<<word<<"]没有兄弟单词"<<endl; }//if else{ cout<<"单词["<<word<<"]有兄弟单词:"; for(int i = 0;i < result.size();++i){ cout<<result[i]<<" "; }//for cout<<endl; } }
引用:
如何找出字典中的兄弟单词
[算法系列之二十]字典树(Trie)
寻找兄弟单词(2012.5.6百度实习)
- [经典面试题][百度]寻找兄弟单词
- 百度面试题--给定一个单词,从字典查找该单词的所有兄弟单词
- 寻找兄弟单词
- 寻找兄弟单词
- 经典面试题---寻找特殊字符
- 经典面试题--字符串按单词逆转
- 九章算法面试题21 寻找最近单词对
- 【面试题】:兄弟字符串
- [经典面试题][百度]电话号码对应英语单词
- 【经典面试题】寻找单链表倒数第n个节点
- 经典面试题:翻转英文句子中单词的顺序
- 2012 百度实习笔试题-兄弟单词
- 百度面试题 字符串中单词的逆转,即将单词出现的顺序进行逆转
- 面试题---单词翻转
- 微软、谷歌、百度等公司经典面试题
- [经典面试题][百度]c++实现STL中的string类
- 剑指offer面试题21包含Min函数的栈 经典的百度面试题
- 兄弟单词
- 别把自己变成了“二等公民”
- synchronized用法
- java中的JSon解析
- ASP.NET MVC在Request中关于URL的参数
- [ios]#import与@class的区别
- [经典面试题][百度]寻找兄弟单词
- poj2970
- 初创互联网公司简明创业指南 - YC新掌门Sam Altman
- 如何在低流量站点进行A/B分离测试?
- Python对MySQL数据库的操作
- Leetcode: Combination Sum
- 【DP】 HDOJ 4284 Travel
- html 页面标签转换效果实例
- OC中Block的使用