给你两个整数数组 nums1
和 nums2
,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[4,9]
提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
题目好理解,看起来很好写,刚开始想的循环两层,遇到相同的就存在新的数组中,但是有一个解决不了的就是,如果有一个数在一个数组中有一个,另一个数组中有两个,那么存在新数组的就有可能是两个(当然经验告诉我们答案应该是只有一个)。
看大佬们的思路,发现了哈希表,之前的题目里,也见过不止一次,但是实在是脑子里没学到哈希表的东西,就一般避开。发现一个大佬的思路写的及其清新易懂,学习了一下,开始第一次与哈希表的接触。
解题思路(大佬写的)
由于题目中数组元素的取值范围为0-1000,故可以定义一个大小为1001的数组,用来存放每一个元素的出现次数,遍历nums1时,将每个元素出现的次数放到table[nums1[i]]对应的位置处,接下来遍历nums2时,根据table[nums2[i]]中的值,如果大于0,表明在nums1中出现过,就把该元素加入到ans中,并将table中的值减1,用于加入所有重复出现的元素。
/** * Note: The returned array must be malloced, assume caller calls free(). */
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
int table[1001];
int count=0;
int* ans=(int*)malloc(sizeof(int)*nums2Size);
memset(table,0,sizeof(table));
for(int i=0;i<nums1Size;i++){
table[nums1[i]]+=1;
}
for(int j=0;j<nums2Size;j++){
if(table[nums2[j]]>0){
ans[count++]=nums2[j];
table[nums2[j]]-=1;
}
}
*returnSize=count; return ans;
}
动态数组原来一行也能搞定
int* ans=(int*)malloc(sizeof(int)*nums2Size);
新的知识:
memset函数,为初始化函数,可以将一段连续的内存初始化为某个值,但它是以字节为单位进行初始化的。
一般格式为memset(首地址,值,sizeof(地址总大小));
(没有这个,上面的代码能运行,结果正确,但是提交时显示错误。)
count一开始觉得没啥用,就没写 *returnSize=count;能运行,结果是],哈哈哈。看起来像是对输出进行修饰的。
真厉害👍
_____________________________________________________________________________
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
List<Integer> list = new ArrayList<>();//定义一个动态集合
Arrays.sort(nums1);
Arrays.sort(nums2);//先分别进行排序
int m=0,n=0;
while(m<nums1.length &&n<nums2.length){
if(nums1[m]<nums2[n]){//此时,和nums2[n]可能相等的值在nums1[m]之后位
m++;
}
else if(nums1[m]>nums2[n]){//同上理
n++;
}
else{
list.add(nums2[n]);//相等时,将此值存放在list集合中
m++;
n++;
}
}
int[] a=new int[list.size()];
int j=0;
for(int i=0;i<list.size();i++){//将集合转换成数组输出
a[j++]=list.get(i);
}
return a;
}
}
哈希表:
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
HashMap<Integer, Integer> hashtable = new HashMap<>();//建立哈希表
ArrayList<Integer> list = new ArrayList<>();//新建动态集合
for(int i=0;i<nums1.length;i++){
//将nums1读入哈希表,(值,出现次数)
hashtable.put(nums1[i],hashtable.getOrDefault(nums1[i],0)+1);
}
for(int i=0;i<nums2.length;i++){
//遍历nums2,如果哈希表中存在
if(hashtable.getOrDefault(nums2[i],0)>0){
list.add(nums2[i]);//将此值添加到数组中
hashtable.put(nums2[i],hashtable.get(nums2[i])-1);//减少此值的出现次数
}
}
int[] a=new int[list.size()];//将集合转换为数组然后输出
int j=0;
for(int i=0;i<list.size();i++){
a[j++]=list.get(i);
}
return a;
}
}