前言
这是六月集训的第七日,今日的训练内容是 哈希表
解题报告
1.力扣442
原题链接
题目概述
给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。
你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题。
解题思路
直接建立一个哈希表,然后将原来的数组中的数都映射到哈希表里,在重新填回到数组中返回即可。
源码剖析
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* findDuplicates(int* nums, int numsSize, int* returnSize){
int hash[100001]={0};
int i = 0,j = 0;
*returnSize = 0;
for(i = 0;i<numsSize;++i){
hash[nums[i]]++;
if(hash[nums[i]]==2) (*returnSize)++;
}
int *ret=(int*)malloc(sizeof(int)*(*returnSize));
for(i = 0;i<100001;++i){
if(hash[i]==2) ret[j++] = i;
}
return ret;
}
2.力扣2068
原题链接
题目概述
如果两个字符串 word1 和 word2 中从 ‘a’ 到 ‘z’ 每一个字母出现频率之差都 不超过 3 ,那么我们称这两个字符串 word1 和 word2 几乎相等 。
给你两个长度都为 n 的字符串 word1 和 word2 ,如果 word1 和 word2 几乎相等 ,请你返回 true ,否则返回 false 。
一个字母 x 的出现 频率 指的是它在字符串中出现的次数。
解题思路
使用字母减去'a'
就可以把字母转换为数字(ascii码),然后就可以填入哈希表,然后再对哈希表的相同位置的元素进行比较就行了。
源码剖析
int *HASH(char*s){
int len = strlen(s);
int *ret = (int*)malloc(sizeof(int)*26);
int i;
for(i = 0;i<len;++i){
ret[s[i]-'a']++;
}
return ret;
}
bool checkAlmostEquivalent(char * word1, char * word2){
int *hash1 = HASH(word1);
int *hash2 = HASH(word2);
int i;
for(i = 0;i<26;++i){
if(abs(hash1[i]-hash2[i])>3) return false;
}
return true;
}
3.力扣2283
原题链接
题目概述
给你一个下标从 0 开始长度为 n 的字符串 num ,它只包含数字。
如果对于 每个 0 <= i < n 的下标 i ,都满足数位 i 在 num 中出现了 num[i]次,那么请你返回 true ,否则返回 false 。
解题思路
其实字符串本身就是一个哈希表,所以把原来的哈希表先填入新的哈希表,再回来对应,就可以解出来了。
源码剖析
bool digitCount(char * num){
int hash[10]={0};
int i,j = 0;
int len = strlen(num);
for(i = 0;i<len;++i){
hash[num[i]-'0']++;
}
for(i = 0;i<len;++i){
if(hash[i]!=num[i]-'0') return false;
}
return true;
}
4.力扣884
原题链接
题目概述
句子 是一串由空格分隔的单词。每个 单词 仅由小写字母组成。
如果某个单词在其中一个句子中恰好出现一次,在另一个句子中却 没有出现 ,那么这个单词就是 不常见的 。
给你两个 句子 s1 和 s2 ,返回所有 不常用单词 的列表。返回列表中单词可以按 任意顺序 组织。
解题思路
思路大概是将每个单词都放入哈希表中,然后遍历哈希表找到那些值出现过一次的单词,再返回,不过用c貌似实现起来比较复杂,先记录一下题目。
源码剖析