LeetCode-1002-查找常用字符-C语言实现

这篇博客探讨了一个编程问题,涉及对仅包含小写字母的字符串数组进行处理,找出所有字符串中共有的字符及其出现次数。通过遍历每个字符串并使用两个计数数组,计算每个字符在所有字符串中的最小出现频率。最后,根据这个频率生成结果列表。示例展示了如何处理'bellla', 'label', 'roller'和'cool', 'lock', 'cook'这两个案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定仅有小写字母组成的字符串数组 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] 是小写字母

根据题目的要求,如果字符 c 在所有字符串中均出现了 k 次及以上,那么最终答案中需要包含 k 个 c。因此,我们可以使用
minfreq[c] 存储字符 c 在所有字符串中出现次数的最小值。

我们可以依次遍历每一个字符串。当我们遍历到字符串 s 时,我们使用 freq[c] 统计 s 中每一个字符 c
出现的次数。在统计完成之后,我们再将每一个]minfreq[c] 更新为其本身与 freq[c]
的较小值。这样一来,当我们遍历完所有字符串后,minfreq[c] 就存储了字符 c在所有字符串中出现次数的最小值。

由于题目保证了所有的字符均为小写字母,因此我们可以用长度为 26 的数组分别表示 minfreq 以及freq。

在构造最终的答案时,我们遍历所有的小写字母 c,并将 minfreq[c] 个 c 添加进答案数组即可。

代码详解,并添加了测试代码:

#include <iostream>
#include <malloc.h>
#include<stdio.h>
using namespace std;
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 /*
	A是一个指向指针的指针,比如char** A = ["bella","label","roller"]
	A是一个指针,它表示A的头元素,也就是A[0],
	A[0]也是个指针,它指向一个字符串,也就是“bella”,它的头元素为A[0][0],也就是‘b’
 */
char** commonChars(char** A, int ASize, int* returnSize) {
	/*
	代码原理:首先记录26个字母在第一个字符串中分别出现的次数,记录在freq1数组中,
				然后记录26个字母分别出现在第二个字符串中的次数,记录在freq2数组中,
				通过对比两个数组中的每一个数据,取最小值,放入minfreq数组中,里面保存的                  是26个字母在这两个字符串中分别都出现的次数
	*/
	//minfreq存放着所有字符串中每个字符分别都出现的次数
	//freq存放着某个字符串中26个字母分别出现的次数
	int minfreq[26], freq[26];
	//先做初始化,freq全置0,minfreq置为最大整数
	for (int i = 0; i < 26; ++i) {
		minfreq[i] = INT_MAX;
		freq[i] = 0;
	}
	//开始计数,遍历每个字符串
	for (int i = 0; i < ASize; ++i) {
		//将freq数组全部置0,重新记录数据
		memset(freq, 0, sizeof(freq));

		//遍历某个字符串的全部字符
		int n = strlen(A[i]);
		for (int j = 0; j < n; ++j) {
			//某个字符与‘a’相减,相减的结果作为数组下标,然后该下标的元素自加1
			//因为是用0-25的下标来表示‘a’到‘z’分别出现的次数
			//假设出现的是‘z’,‘z’-‘a’等于25,下标为25的元素自加一
			++freq[A[i][j] - 'a'];
		}

		//得到26个字母在该字符串的出现次数后,与minfreq逐个进行对比,取最小值
		for (int j = 0; j < 26; ++j) {
			minfreq[j] = fmin(minfreq[j], freq[j]);
		}
	}

	//得到26个字母在全部的字符串中出现的字数后,需要为返回的数组分配空间
	//依题意,假设‘a’出现了两次,则数组中需要有两个‘a’
	//所以将minfreq数组中的数值累加,就是需返回数组中的字符个数,也就是所需的指针的个数
	int sum = 0;
	for (int i = 0; i < 26; ++i) {
		sum += minfreq[i];
	}

	//返回的是一个指向指针的指针,所以需要分配的是指针的内存大小
	//开辟一块内存用于存放sum个指针
	char** ans = (char**) malloc(sizeof(char*) * sum);
	//返回的数组大小
	*returnSize = 0;
	//将出现次数转成字母存放着ans数组中
	for (int i = 0; i < 26; ++i) {
		for (int j = 0; j < minfreq[i]; ++j) {
			//由于题目要求返回的元素是字符串,
			//所以需要给char类型的数组分配两个char的内存空间
			ans[*returnSize] = (char *) malloc(sizeof(char) * 2);
			ans[*returnSize][0] = i + 'a';
			ans[*returnSize][1] = '\0';
			(*returnSize)++;
		}
	}
	//事实上,*returnSize == sum;
	return ans;
}
int main()
{
	//为commonChars函数编写驱动程序
	char** A = new char*[3];
	char c[] = "bella";
	char d[] = "lebel";
	char e[] = "roller";
	A[0] = c;
	A[1] = d;
	A[2] = e;
	int a = 0;
	int *b = &a;
	char ** ans = commonChars(A, 3, b);
	cout << "The ans is:" << endl;
	cout << "returnSize = "<< *b << endl;
	for (int i = 0; i < 3; i++)
		cout << ans[i] << endl;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SOC罗三炮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值