两个数组的交集(初用哈希表)(力扣)

给你两个整数数组 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;



    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值