小白跟随卡哥刷题第十二天(hash表部分)

一、前言

个人感觉今天的题目应该是卡哥让各位放松一天的小惊喜,说实话其思路是不难的,甚至是简单的。但是比较了map和卡哥提醒的vector两种方法,我们也可以非常直接看出map的复杂度比vector要高得多,这也提醒了我,注意hash表的选择吧。话不多说直接进入题目吧。

二、题目(力扣第383题—赎金信. - 力扣(LeetCode)

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。如果可以,返回 true ;否则返回 false 。

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

示例 1:
输入:ransomNote = "a", magazine = "b"
输出:false
示例 2:
输入:ransomNote = "aa", magazine = "ab"
输出:false
示例 3:
输入:ransomNote = "aa", magazine = "aab"
输出:true

三、题解

这里的构成,不仅是ran中的字母种类与mag中字母种类对应,而且ran中对应字母的个数也要在mag中对应(或者说mag中的对应字母个数和数量要大于等于ran中的字母个数和数量即可),这里类似于包含的关系,mag包含ran。(我将卡哥的讲解放到这里代码随想录

个人思路:

我先说说我的思路,我看见本题的思路也很简单、直接,顺着这几天的hash思路,我想可以将两个字符串分别存入两个map中,map的key来存字母种类,map的value来存字母出现的数量,然后两个map进行比较即可。

接下来就详细讲讲我的代码,先将完整代码放到这里。

bool canConstruct(string ransomNote, string magazine) {
	int len1=ransomNote.size();
	int len2=magazine.size();
	if(len1>len2)return false;
	else{
	unordered_map<char,int> ran,mag;
	for(auto it:magazine){
		mag[it]++;
	}
	for(auto it:ransomNote){
		ran[it]++;
		if((mag.find(it)==mag.end())||(mag[it]<ran[it]))return false;
	}
	return true;
	}
}

这里先进行一下简单的判断,如果ran的长度比mag大,那么一定是false的。

int len1=ransomNote.size();
int len2=magazine.size();
if(len1>len2)return false;//如果ran的长度大于mag,那么一定是false

定义了两个unordered_map来存放ran和mag的字母及出现次数。

两个遍历将字母和次数存入ran和mag中。

unordered_map<char,int> ran,mag;
	for(auto it:magazine){
		mag[it]++;
	}
	for(auto it:ransomNote){
		ran[it]++;

	}

这里是判断,ran中的字母是否在mag中,并且mag中该字母出现的次数比ran中的字数要多,否则就是false。

	if((mag.find(it)==mag.end())||(mag[it]<ran[it]))return false;

思路比较:

看过卡哥讲解的uu会发现,卡哥的两种思路都是基于数组来实现的,其中第一种是最简单的暴力解法也就是两重循环,另一种就是基于数组的hash解法(这种方法在前面我们也遇见过,也详细说过),而我的思路则是基于map的hash解法,因此这三种思路都是可以通过的,但是我们可以在力扣上清晰的看见三者的差别,其中基于数组的hash解法时间是最快的,只有基于map的hash解法的1/3,其次是基于map的hash解法,最慢的则是基于数组的暴力解法(如下图)。我们可以发现好的算法应该具有更高的效率,更简单的数据结构,在面对海量的数据时才会有更好的表现!因此我们不应该一味的追求复杂的数据结构,有时候能用简单的数据结构解决的算法,反而更加亮眼。

四、后记

今天的题也算是提醒了我,有时候更简单的数据结构会有更好的表现,会有更高的效率。各位uu也要加油,努力刷题,好好生活呀!又要将近期末,我的本科生活也要到此结束了,希望各位uu们也加油,咱们下一个阶段再见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值