LeetCode---Hash应用2

LeetCode刷题笔记(C语言)

Hash应用

题二、给你一个字符串数组 words ,请你找出所有在 words 的每个字符串中都出现的共用字符(包括重复字符),并以数组形式返回。你可以按任意顺序返回答案。

在这里插入图片描述

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 100
  • words[i] 由小写英文字母组成
方法一:使用哈希(Hash)进行查询统计出共用(及重复)的字符。

原因:使用此方法的原因是因为题目让我们找出每个字符串的共用字符,而字符串的字符本身的英文字母ANSI码就与数组下标有对应的线性关系,因此构成了一个哈希表(也就是以为数组),所以我们可以将每一个字符串建立对应的哈希表,也就是二位数组了,如下图所示。
在这里插入图片描述
上图对应的程序为:

18.	    /* 将每个字符串出现的字符个数统计到其对应的Hash表中 */  
19.	    for(x = 0;x < wordsSize;x++) {  
20.	        //printf("%s字符串字母个数%d\r\n",*(words),strlen(*(words+x)));  
21.	        for(i = 0;i < strlen(*(words+x));i++) {  
22.	            //printf("第%d个字符串,第%d个字母:%c\r\n",x,i,*((*(words+x))+i));  
23.	            y = (int)(*((*(words+x))+i) - 'a');     //某个字符串对应的Hash表下标  
24.	            HashMap[x][y] += 1;                     //统计出现的英文字母个数  
25.	        }  
26.	    }

通过哈希表方法统计出了每个字符串对应出现的字符个数,那么我们就需要对每个字符串中的每个字符个数就行两两比较,查找出所有字符串的共用字符(使用打擂台算法)。
在这里插入图片描述
上图对应的程序为:

27.	    /* 比较每个字符串某个字母的统计个数,找出统计出现的字母个数最少的值 */  
28.	    for(y = 0;y < 26;y++) {  
29.	        for(x = 0;x < wordsSize;x++) {  
30.	            if(x == 0) min = HashMap[x][y];  
31.	            else if(min > HashMap[x][y]) min = HashMap[x][y];   //获取对应字母的最小统计值     
32.	        }  
33.	        /* 当满足最小值大于零,说明,该字母在每个字符串都出现了,即为共用字符 */   
34.	        // if(min > 0) {                                             
35.	        //     //printf("共用字母%c的个数:%d\r\n",(char)(y+(int)'a'),min);      
36.	        // }   
37.	        /* 将共用的字母以字符串方式统计到返回值变量中 */                                       
38.	        for(i = 0;i < min;i++) {     
39.	            rep_char[*returnSize] = malloc(sizeof(char)*2);         //一个字母为字符串,那么为两个字节空间,例如"a" = 'a' + 0  
40.	            rep_char[*returnSize][0] = y + 'a';  
41.	            rep_char[*returnSize][1] = 0;                 
42.	            (*returnSize)++;                                       //该字母重复字符个数累加  
43.	        }              
44.	          
45.	    } 

通过上面两个步骤分解,基本就得出了题目想要实现的功能了。题目完整的程序如下:

1.	/** 
2.	 * Note: The returned array must be malloced, assume caller calls free(). 
3.	 */  
4.	 /* words:字符串数组,wordsize:字符串输出的字符串个数,returnSize:重复字符的个数 */  
5.	char ** commonChars(char ** words, int wordsSize, int* returnSize){  
6.	    /* 
7.	     *  x为字符串循环变量(下标) 
8.	     *  y为英文字母的循环变量(下标) 
9.	     *  i为每个字符串的字符循环变量 
10.	     *  min存储每个重复字母的个数 
11.	     */  
12.	    int x,y,i,min;  
13.	    int HashMap[wordsSize][26];                     //统计每个字符串对应下的每个英文字母出现的个数  
14.	    char** rep_char = malloc(sizeof(char*) * 100);  //用于保存共用字符(包括重复字符)  
15.	    memset(HashMap,0,sizeof(HashMap));              //清空二维数组Hash表  
16.	    x = y = i = *returnSize = 0;        //初始化变量  
17.	  
18.	    /* 将每个字符串出现的字符个数统计到其对应的Hash表中 */  
19.	    for(x = 0;x < wordsSize;x++) {  
20.	        //printf("%s字符串字母个数%d\r\n",*(words),strlen(*(words+x)));  
21.	        for(i = 0;i < strlen(*(words+x));i++) {  
22.	            //printf("第%d个字符串,第%d个字母:%c\r\n",x,i,*((*(words+x))+i));  
23.	            y = (int)(*((*(words+x))+i) - 'a');     //某个字符串对应的Hash表下标  
24.	            HashMap[x][y] += 1;                     //统计出现的英文字母个数  
25.	        }  
26.	    }  
27.	    /* 比较每个字符串某个字母的统计个数,找出统计出现的字母个数最少的值 */  
28.	    for(y = 0;y < 26;y++) {  
29.	        for(x = 0;x < wordsSize;x++) {  
30.	            if(x == 0) min = HashMap[x][y];  
31.	            else if(min > HashMap[x][y]) min = HashMap[x][y];   //获取对应字母的最小统计值     
32.	        }  
33.	        /* 当满足最小值大于零,说明,该字母在每个字符串都出现了,即为共用字符 */   
34.	        // if(min > 0) {                                             
35.	        //     //printf("共用字母%c的个数:%d\r\n",(char)(y+(int)'a'),min);      
36.	        // }   
37.	        /* 将共用的字母以字符串方式统计到返回值变量中 */                                       
38.	        for(i = 0;i < min;i++) {     
39.	            rep_char[*returnSize] = malloc(sizeof(char)*2);         //一个字母为字符串,那么为两个字节空间,例如"a" = 'a' + 0  
40.	            rep_char[*returnSize][0] = y + 'a';  
41.	            rep_char[*returnSize][1] = 0;                 
42.	            (*returnSize)++;                                       //该字母重复字符个数累加  
43.	        }              
44.	          
45.	    }   
46.	    // printf("重复个数:%d, 重复字母:%s,%s,%s\r\n",*returnSize,ans[0],ans[1],ans[2]);  
47.	    return rep_char;                                                    //共用字母字符串数组返回值  
48.	}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邓家文007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值