首页 > 其他分享 >C语言 | Leetcode C语言题解之第187题重复的DNA序列

C语言 | Leetcode C语言题解之第187题重复的DNA序列

时间:2024-06-24 13:30:54浏览次数:20  
标签:DNA int 题解 hashHead C语言 char obj stringKey NULL

题目:

题解:

#define MAXSIZE 769/* 选取一个质数即可 */
typedef struct Node 
{
    char    string[101];
    int     index;
    struct Node *next;  //保存链表表头
} List;

typedef struct 
{
    List *hashHead[MAXSIZE];//定义哈希数组的大小
} MyHashMap;

List * isInHash(List *list,char * stringKey) 
{
    List *nodeIt = list;
    //通过链表下遍历
    while (nodeIt != NULL) 
    {
        if (strcmp(stringKey, nodeIt->string)== 0 ) 
        {
            return nodeIt;
        }
        nodeIt = nodeIt->next;
    }
    return NULL;
}

MyHashMap* myHashMapCreate() 
{
    int i;
    MyHashMap* newHash= (MyHashMap* )malloc(sizeof(MyHashMap));
    /* 对链表的头结点赋初值 */
    for (i = 0; i < MAXSIZE; i++)
    {
        newHash->hashHead[i] = NULL;
    }
    return newHash;
}

int myHashID(char * str)
{
    long h = 0;
    for(int i = 0; i < strlen(str); i++)
    {
        h = (h * 26 % MAXSIZE + str[i] - 'A') % MAXSIZE; 
        // 字符串的hashcode, 权为26是因为小写字母,不限制时为128,这样能够让结点尽可能分布均匀,减少地址冲突
        // 取模是为了防止int型溢出
    }
    return h % MAXSIZE;
}


void myHashMapPut(MyHashMap* obj, char* stringKey,int index) 
{
    //一定不再这里面
    List * it= isInHash(obj->hashHead[myHashID(stringKey)],stringKey);
    if(it != NULL)
    {
        //在表里面更新键值
        it->index = index;
    }
    else
    {
        //不在表里面
        List *newNode       = (List*)malloc(sizeof(List));
        strcpy(newNode->string , stringKey);
        newNode->next       = NULL;
        newNode->index      = index;
        if(obj->hashHead[myHashID(stringKey)] != NULL)
        {
            //当前头链表不为空,则需要将后续的链表接上
            //需要主要这里表头也代表一个数据的值
            newNode->next = obj->hashHead[myHashID(stringKey)];
        }
        //修改头链表
        obj->hashHead[myHashID(stringKey)] =  newNode;
    }
}

int myHashMapGet(MyHashMap* obj, char* stringKey) 
{
    List * it= isInHash(obj->hashHead[myHashID(stringKey)],stringKey);
    if( it!= NULL)
    {
        return it->index;
    }
    return -1;
}

void myHashMapFree(MyHashMap* obj) 
{
   int i;
   List *freeIt;
   List *curIt;
   for (i = 0; i < MAXSIZE; i++)
    {
        if(obj->hashHead[i] != NULL)
        {
            freeIt = NULL;
            curIt  = obj->hashHead[i];
            
            while(curIt != NULL)
            {
                freeIt = curIt;
                curIt= curIt->next;
                free(freeIt);
            }
            obj->hashHead[i]= NULL;
        }
    }
    free(obj);
}


char ** findRepeatedDnaSequences(char * s, int* returnSize)
{
    char* stringKey = (char * )malloc(sizeof(char ) * 11);
    int len = strlen(s);
    if(len < 10)
    {
        *returnSize = 0;
        return NULL;
    }

    MyHashMap * hsahMap = myHashMapCreate();
    int maxCount = 0;
    for(int i = 10; i <= len; i++)
    {
        memcpy(stringKey, &s[i-10], 10);
        stringKey[10] = '\0';
        int count = myHashMapGet(hsahMap, stringKey);
        if(count == -1)
        {
            count = 1;
            
        }
        else
        {
            count++;
        }
        myHashMapPut(hsahMap,stringKey,count);
        maxCount = fmax(maxCount, count);
    }

    if(maxCount < 2)
    {
        *returnSize = 0;
        return NULL;
    }

    *returnSize = 0;
    char ** returnMatStr = (char ** )malloc(sizeof(char *) * len);
    int i;
    List *freeIt;
    List *curIt;
    for (i = 0; i < MAXSIZE; i++)
    {
        if(hsahMap->hashHead[i] != NULL)
        {
            freeIt = NULL;
            curIt  = hsahMap->hashHead[i];
            
            while(curIt != NULL)
            {
                freeIt = curIt;
                curIt= curIt->next;
                if(freeIt->index == maxCount)
                {
                    returnMatStr[*returnSize] = (char * )malloc(sizeof(char ) * 11);
                    strcpy(returnMatStr[*returnSize],  freeIt->string);
                    *returnSize = *returnSize + 1;
                }
                free(freeIt);
            }
            hsahMap->hashHead[i]= NULL;
        }
    }
    free(hsahMap);
    return returnMatStr;
}

标签:DNA,int,题解,hashHead,C语言,char,obj,stringKey,NULL
From: https://blog.csdn.net/m0_59237910/article/details/139910758

相关文章

  • LeetCode11. 盛最多水的容器题解
    LeetCode11.盛最多水的容器题解题目链接:https://leetcode.cn/problems/container-with-most-water示例思路暴力解法定住一个柱子不动,然后用其他柱子与其围住面积,取最大值。代码如下:publicintmaxArea1(int[]height){intn=height.length;intans=0;......
  • [题解]CF1716D Chip Move
    思路Part1这种题目应该能一眼看出是DP。我们令\(dp_{i,j}\)表示走到\(j\)这个位置,最后一步花了\(i\)的倍数。那么,我们的方程就很好想了:\(dp_{i,j}=\sum_{k=1}^{j-k\timesi\geq0}dp_{i-1,j-k\timesi}\)。因为,我们走到\(j\)的位置只能走\(i\)的倍......
  • [题解]CF1714F Build a Tree and That Is It
    思路由于题目中说这是一棵无根树,不太方便思考,于是,我们可以假装把这棵树看做有根树。首先我们令\(d_1,d_2,d_3\)分别表示从根节点到节点\(1,2,3\)的长度(不算相交部分)。那么我们可以得到下式:\[\left\{\begin{matrix}d_{12}=d_1+d_2\\d_{13}=d_1+d_3\\......
  • [题解]CF1712E1 LCM Sum (easy version)
    思路这是一道极好的思维题,主要考察了:组合数学和正难则反的方法。这题可以发现如果用直接法将十分的繁琐,于是乎,我们可以用正难则反的方法,即:总的减去不满足的。这道题总的很好求,为:\(C_{r-l+1}^{3}\)。不满足的情况,我们就可以将题目转化为:\(\operatorname{lcm}(i,j,k)<i+......
  • [题解]CF1712D Empty Graph
    思路因为我们枚举的直径是具备单调性的,所以可以使用二分答案。我们可以想一个事情,如果有两个点\(u\)和\(v\),它们两点之间的最短路径要么是直接从\(u\tov\);要么是经过一个中转点\(t\),即:\(u\tot\tov\)。然后,我们可以发现一个显然的规律,就是\(t\)一定是区间\(a\)中......
  • [题解]CF1704D Magical Array
    题意给定\(n\)个长度为\(m\)的数组,对于每一个数组选择下面任意一种操作进行若干次(操作二只能被一个数组选出)。\(c_{t,i}-1,c_{t,i-1}+1,c_{t,j}-1,c_{t,j-1}+1\)。\(c_{t,i}-1,c_{t,i-1}+1,c_{t,j}-1,c_{t,j-2}+1\)。最后输出选择操作二的数组......
  • [题解]CF1665E MinimizOR
    思路发现\(2^k\)大的数,最终的答案一定由前\(k+1\)小的元素组成。考虑数学归纳法,显然当\(k=1\)成立。假令\(k'\)时成立,证明\(k=k'+1\)时成立即可:若第\(k\)位有两个及以上的\(0\),显然最终答案的第\(k\)位一定为\(0\),因此考虑前面的\(k-1\)位,显然取......
  • [题解]CF1473D Program
    思路因为此题目中对于数的更新只能为\(1\),所以,如果我们找到了\([1,l-1]\)与\([r+1,n]\)中能获得的两个极值即可。我们为\(S\)赋予权值,用一个数组\(a\)储存:如果\(S_i\)为+,则其权值为\(1\)。否则其权值为\(-1\)。那么,在第\(i\)次操作后,能产生的数是\(\s......
  • [题解]CF1312E Array Shrinking
    思路本题为P3146变式,也算是一道很经典的区间DP题了。因为\(n\leq500\),考虑区间DP。定义\(dp_{i,j}\)表示操作\([i,j]\)区间剩余长度的最小值。那么,我们可以枚举一个中间值\(k\),可以显然地得到一个状态转移方程(即不能合二为一的情况):\[dp_{i,j}=\min(dp_{i,......
  • [题解]CF1223F Stack Exterminable Arrays
    CCF出的原题观摩一下。思路首先可以用一个Trie来维护。在这里对本文中的一些变量做一下说明。\(p\)表示当前维护的Trie中,指向的元素编号。\(t_i\)表示在Trie中编号为\(i\)的元素在原序列中的值。\(f_i\)表示在Trie中编号为\(i\)的元素在Trie中的父节点。......