变位词

题目描述:

如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,比如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的所有兄弟单词。

这种方法理解需要以后补充

变位词,布布扣,bubuko.com

时间: 2024-08-03 19:22:48

变位词的相关文章

写一个函数对字符串数组排序,使所有变位词都相邻

题目 写一个函数对字符串数组排序,使得所有的变位词都相邻. 解答 首先,要弄清楚什么是变位词.变位词就是组成的字母相同,但顺序不一样的单词. 比如说:live和evil就是一对变位词.OK,那么这道题目的意思就很清楚了, 它并不要求我们将字符串数组中的字符串按字典序排序,否则我们直接调用STL中的sort 函数就可以了.它要求我们在排序的过程中,按照变位词的准则来排序. 这种情况下,我们还是可以调用sort函数,不过要自己写一个对比函数. 一般情况下我们如果要排序一个长度为n的数组A,我们可以这

005推断两个字符串是否是变位词 (keep it up)

写一个函数推断两个字符串是否是变位词. 变位词(anagrams)指的是组成两个单词的字符同样,但位置不同的单词.比方说, abbcd和abcdb就是一对变位词 这也是简单的题. 我们能够排序然后对照, 也能够直接统计字符出现的个数来推断.这里给出统计字符来推断的代码: bool isAnagram1(const string& vLeft, const string& vRight) { if (vLeft.size() != vRight.size()) return false; i

变位词的查找(上)

本文也同步发表在我的公众号"我的天空" 这次我们聊一个比较有意思的话题:变位词的查找,这个话题在<编程珠玑>中出现,此书很经典,偏向于算法,大家如果能通读的话,肯定受益匪浅!   什么是变位词 不同的单词,如果其组成的字母相同的话,那么这些单词就互为变位词,譬如pots.stop. tops这三个单词就是互为变位词,都是由字母p.o.t.s组成,但是"pot" 就不与上述单词互为变位词,其缺少字母s,"potss"也不是,其多了一个字

互为变位词

// 判断两个单词是否互为变位词: 如果两个单词中的字母相同,并且每个字母出现的次数也相同, 那么这两个单词互为变位词 #include <stdio.h> #include <string.h> int is_anagram(char *s1, char *s2) // 判断两个数是否互为变位词, 若是返回1 { if(strlen(s1) != strlen(s2)) return 0; int count[256] = {0}; char *p; p = s1; while(

CareerCup之1.4判断字符串是否为变位词

[题目] 原文: 1.4 Write a method to decide if two strings are anagrams or not. 译文: 写一个函数判断两个字符串是否是变位词. [分析] 变位词(anagrams)指的是组成两个单词的字符相同,但位置不同的单词.比如说, abbcd和abcdb就是一对变位词.该题目有两种思路: [思路一] 由于变位词只是字母的顺序改变,字符长度,字符种类没有改变,所以根据此我们只要重新根据字典序排序一下,两个字符串也就一样了. The eyes

变位词排序

题目描述 请编写一个方法,对一个字符串数组进行排序,将所有变位词合并,保留其字典序最小的一个串.这里的变位词指变换其字母顺序所构成的新的词或短语.例如"triangle"和"integral"就是变位词. 给定一个string的数组str和数组大小int n,请返回排序合并后的数组.保证字符串串长小于等于20,数组大小小于等于300. 测试样例: ["ab","ba","abc","cba&quo

判断两个字符串是否是变位词 (keep it up)

写一个函数判断两个字符串是否是变位词.变位词(anagrams)指的是组成两个单词的字符相同,但位置不同的单词.比如说, abbcd和abcdb就是一对变位词 这也是简单的题. 我们可以排序然后对比, 也可以直接统计字符出现的个数来判断.这里给出统计字符来判断的代码: bool isAnagram1(const string& vLeft, const string& vRight) { if (vLeft.size() != vRight.size()) return false; in

变位词的查找(下)

本文也同步发表在我的公众号"我的天空" 实现方案优劣的思考 之前我们的实现方案的优点是一旦目标词库的签名建立后,则变位词的查找会变得简单而快速:缺点是由于在生成目标词库时,要为每个词都生成签名,导致生成词库的时间会变慢,同时会消耗空间.对于那些没有被查找到的字符串的签名实际上是浪费的. 测试结果:在CPU为Inter Core i3-2328M,内存为6GB的PC上生成数量为1万的目标词库平均时间为377毫秒,查找变位词的平均时间为11毫秒.   第二种方案 在生成目标词库的时候并不生

9.11排序与查找(二)——对字符串数组进行排序,将所有的变位词排在相邻的位置

/** * 功能:对字符串数组进行排序,将所有的变位词排在相邻的位置. */ 两种方法: 方法一: /** * 思路:套用排序算法,并修改比较器.这里比较器用来指示两个字符串胡伟变位词就是相等的. * @param array */ public static void sort(String[] array){ Arrays.sort(array, new AnagramComparator()); } class AnagramComparator implements Comparator