题目描写叙述:
假设两个字符串的字符一样,可是顺序不一样,被觉得是兄弟字符串,比方bad和adb即为兄弟字符串。现提供一个字符串,怎样在字典中迅速找到它的兄弟字符串。请描写叙述数据结构和查询过程。
思路一:用计数排序
设计一个数组,对单词每一个字母计数加1。对兄弟单词每一个字母计数减去1,假设最后这个数组的计数是0,那么就为兄弟单词
bool isBrotherWord(string &str1, string &str2)
{
int len1 = str1.length();
int len2 = str2.length();
//长度不相等。肯定不是兄弟单词
if(len1 != len2)
return false;
//设计一个数组,而且初始化为0
int a[26] = {0};
//计数
for(int i = 0;i < len1; i++)
{
a[str1[i] - 'A']++;
a[str2[i] - 'A']--;
}
//假设最后计数不为0,那么就不为兄弟单词
for(int i = 0; i < len1; i++)
{
if(a[str1[i] - 'A'] != 0)
return false;
}
return true;
}
思路二:哈希表
①先创建哈希表。统计字符串1中出现的次数;
②将哈希表扫描第二个字符串时。扫描到每一个字符时候,为哈希表减去1,
③假设最后哈希表全部的值都为0,则为变位词。否则不是变位词
bool isBrotherWord(char *str1, char *str2)
{
//输入不合法
if(str1 == NULL || str2 == NULL)
return 0;
//创建哈希表,而且初始化哈希表
const int tableSize = 256;
unsigned int hashTable[tableSize];
for(int i = 0;i<tableSize;i++)
hashTable[i] = 0;
char *pHashKey = str1;
while(*pHashKey)
{
hashTable[*pHashKey]++;
pHashKey ++;
}
char *pHashKey1 = str2;
while(*pHashKey1)
{
hashTable[*pHaKey1]--;
pHashKey1 ++;
}
if(hashTable[*pHashKey1] == 0)
return true;
return false;
}
思路三:使用哈希表和链表
①将单词按字母从小到大的顺序又一次排序后作为其key,使用链表将全部兄弟单词串在一起hash_map的key为单词的key。value为链表的起始地址。
②遍历字典。将每一个单词都依照key增加到相应的链表中。当须要找兄弟单词时候。仅仅须要取这个单词的key。之后到hash_map中找到相应的链表就可以。
创建哈希表时间复杂度为O(n)。查找兄弟单词时间复杂度为O(1)
思路四:使用哈希表和链表
①将每一个字母相应一个质数,之后让相应的质数相乘,将得到的值放入哈希表中作为key
②使用链表将全部兄弟单词串在一起
③用户输入单词。我们之间遍历哈希表。将链表遍历输出得到全部的兄弟单词。
创建哈希表时间复杂度为O(n),查找兄弟单词时间复杂度为O(1)
思路四:使用trie树
在字典树前缀中再存储一个vector结构的容器
struct word
{
vector<string> brother;//用于保存每一个单词的兄弟单词
word *next[26]; //字典树中每一个节点代表一个字符。并指向下一个字符
};
首先依据字典中的单词来建立字典树,建立的时候。须要略微特殊处理一下,就是比方pots、stop和tops互为兄弟单词,那么在字典中依照首字母顺序的话,应该先遇到pots单词,那么我首先对其进行排序,结果是opts。那么字典树中就分别建立4个节点,分别为o->p->t->s,当然这个是不同层次的,在节点s处的vector容器brother中加入单词pots,遇到stop的时候,相同的方法,排序是opts,此时发现这4个节点已经建立了,那么仅仅须要在第四个节点s处的vector容器brother中加入单词stop,tops单词的处理方法是相同的。
这样建立完字典树后,查询兄弟单词的效率就会非常高了。比哈希的效率还要高。查到tops的兄弟的单词的时候。首先排序,那么就是opts。然后在字典树中查找opts。在s处将其vector容器brother中的的单词输出就是tops的全部兄弟单词。
这样的方法理解须要以后补充