383. 赎金信-力扣

题目要求:给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

这道题是对两个字符数组进行处理。首先考虑所有情况。

由于所有字符都只能使用一次,所以当magazine中的字符数少于ransomNote时,恒为false。

当满足数量要求后,可以比较两字符串中的字母数量。利用嵌套for循环可以实现字母的匹配。将找到的两字母置为其对应的大写。目的是不影响后续的循环检查。

#include<string.h>
bool canConstruct(char* ransomNote, char* magazine) {
	if (strlen(ransomNote) > strlen(magazine))
		return 0;
	int make = 0;
	for (int i = 0; i < strlen(ransomNote); i++)
	{
		for (int j = 0; j < strlen(magazine); j++)
		{
			if (ransomNote[i] == magazine[j])
			{
				ransomNote[i]-=32;
				magazine[j] -=32;
				make++;
			}
		}
	}
	if (make == strlen(ransomNote))
		return 1;
	else
		return 0;

}

显然,这么多字符对比肯定超出时间限制

嵌套的for循环让时间复杂度上了一个量级,如何减少时间复杂度呢?

减少for循环的嵌套层数。

这道题要求统计的是26个字母的种类和个数。字母范围已知。所以我们可以定义一个整型数组,利用一层for循环统计 magazine 中每个字母出现的次数。之后再利用一层for循环统计ransomNote中各字母出现的次数。当ransomNote中出现某一个字母时便减去整型数组中对应角标中的数字。当数字小于0时则证明magazine 不存在对应数量的字符。一层for循环即解决了问题。

#include<string.h>
bool canConstruct(char* ransomNote, char* magazine)
{
	int c[26] = { 0 };
	if (strlen(ransomNote) > strlen(magazine))
		return false;
	for (int i = 0; i < strlen(magazine); i++)
	{
		c[magazine[i] - 'a']++;
	}
	for (int i = 0; i < strlen(ransomNote); i++)
	{
		c[ransomNote[i] - 'a']--;
		if (c[ransomNote[i] - 'a'] < 0)
			return false;

		
	}

	return true;
}

通过了! 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值