-
Notifications
You must be signed in to change notification settings - Fork 9
/
(*字符串操作-二维字符串数组)1002、查找常用字符串
112 lines (93 loc) · 3.69 KB
/
(*字符串操作-二维字符串数组)1002、查找常用字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
给定仅有小写字母组成的字符串数组 A,返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表。例如,如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次。
你可以按任意顺序返回答案。
示例 1:
输入:["bella","label","roller"]
输出:["e","l","l"]
示例 2:
输入:["cool","lock","cook"]
输出:["c","o"]
提示:
1 <= A.length <= 100
1 <= A[i].length <= 100
A[i][j] 是小写字母
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int min(int a,int b)
{
if(a>b) return b;
return a;
}
char **commonChars(char **A, int ASize, int *returnSize)
{
char cnt[26];
memset(cnt,127,26);
char current[26] = {0};
char** result = (char**)malloc(sizeof(char*) * 1000);
for(int i = 0; i < ASize; i++)
{
char* p = A[i];
while(*p != '\0')
{
current[*p-'a']++;
p++;
}
for(int j = 0; j < 26; j++)
{
cnt[j] = min(cnt[j],current[j]);
current[j] = 0;
}
}
*returnSize = 0;
for(int i = 0; i < 26; i++)
{
for(int j = 0; j < cnt[i]; j++)
{
result[*returnSize] = malloc(sizeof(char) * 2);
result[*returnSize][0] = 'a' + i;
result[*returnSize][1] = '\0';
*returnSize = *returnSize + 1;
}
}
return result;
}
/*
这道题拿C语言编程的重点是熟练掌握二维数组的构建与赋值。
从思路上来说,本题可以理解为求每个字符串之间字符数量的交集,比如:
输入:["bella","label","roller"]
输出:["e","l","l"]
第一个字符串的字符数量列表为:
b 1
e 1
l 2
a 1
第二个字符串的字符数量列表为:
l 2
a 1
b 1
e 1
第三个字符串的字符数量列表为:
r 2
o 1
l 2
e 1
三个列表求交集得:
e 1
l 2
然后按照交集中所列的字符和对应的个数,输出至最终结果即可。
这里拿C语言编程,其关键是数组的灵活运用。
首先,如何记录每个字符串中的每个字符的数量?
这使用哈希表的思想,构建26个字符的数量记录表current[26],用来记录当前字符串中每个字符出现的数字的个数,
其中key值为字母在字母表中的位置,value值为该字母在本字符串中出现的次数。但是这里只是记录了每个字符中
字符的个数,并且current中在记录完当前字符串后就会被清零,外层循环会将遍历字符串的指针指向下一个字符串。
所以为了得到所有字符串的字符数量列表的交集,必须为每个字符串都建立一个哈希表,才能求交集吗?答案是否定的。
观察可知,最后交集列表中的数据是每个字符串的字符数量列表中的最少的那个(因为保证是交集,所以要求是每个字符串都要有)
cnt[j]里存储的是前面字符串里的字符个数,current[j]里存储的是当前字符串里对应字符的个数,所以每次循环只需要
保留最小的那个,那么循环下来,cnt里存储的就是字符串列表的交集了。
得到列表交集之后,按照交集里的字符和字符数量构建最后的结果字符串数组即可。
这里需要注意的是结果字符串也是一个二维字符串数组,所以每个元素都是一个完整的字符串,都要有字符串结束符。
最后对*returnSize的自增不能使用*returnSize++,因为自增运算是先赋值,再加一,直接使用自增运算会使最后结束循环时,
返回的returnSize的值比最终的正确结果少1,从而导致结果出错。
*/