leetcode刷题350 两个数组的交集II Intersection of Two Arrays II(简单) Python Java

本文探讨了计算两个数组交集的多种算法实现,包括直接查找、排序后错位遍历以及哈希表统计方法。通过对比不同场景下的最优解,如数组已排序或存在大小差异,提供了一种高效解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]

示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]

说明:

  • 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
  • 我们可以不考虑输出结果的顺序。

进阶:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

解法一:效率比较低

class Solution(object):
    def intersect(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        res = []
        for k in nums1:
            if k in nums2:
                res.append(k)
                nums2.remove(k)
        return res

解法二:先排序,因为两只数组已经按升序排好序,所以当 i 指针和 j 指针指向的数值相等时,放入新list;如果 i 指针指向的数 < j 指针指向的数,那么 i 指针前进;如果 i 指针指向的数 > j 指针指向的数,那么 j 指针前进; 错位遍历。

class Solution(object):
    def intersect(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        ans = []
        nums1.sort()
        nums2.sort()
        i = j = 0
        while i<len(nums1) and j<len(nums2):
            if nums1[i] == nums2[j]:
                ans.append(nums1[i])
                i+=1
                j+=1
            elif nums1[i] < nums2[j]:
                i+=1
            else:
                j+=1
        return ans

 

以下是Java版本:

这道题是之前那道Intersection of Two Arrays的拓展,不同之处在于这道题允许我们返回重复的数字,而且是尽可能多的返回,之前那道题是说有重复的数字只返回一个就行。那么这道题我们用哈希表来建立nums1中字符和其出现个数之间的映射, 然后遍历nums2数组,如果当前字符在哈希表中的个数大于0,则将此字符加入结果res中,然后哈希表的对应值自减1

题意: 求两个数组的交集(包括重复出现的元素)。

思路: 1.遍历数组nums1,将其中的元素放入HashMap<Integer,Integer>中进行统计; 
2.新建ArrayList作为存储交集的元素(可重复元素); 
3.遍历数组nums2,如果元素num2map中出现过,则将其加入到list中,并将其对应的值-1; 
4.
list转为数组返回即可。

public class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Map<Integer,Integer> map = new HashMap<Integer,Integer>();
        for(int num1:nums1){
            if(!map.containsKey(num1)){
                map.put(num1,1);    
            }else{
                map.put(num1,map.get(num1) + 1);         
            }
        }
        List<Integer> list = new ArrayList<Integer>();
        for(int num2:nums2){
            if(map.containsKey(num2) && map.get(num2) > 0){
                list.add(num2);
                map.put(num2,map.get(num2) - 1);
            }
        }
        int[] res = new int[list.size()];
        for(int i = 0;i < list.size();i++){
            res[i] = list.get(i);
        }
        return res;
    }
}

思路:

承接上题Intersection of Two Arrays

不同的是,这里可以有重复元素。因此使用List即可。

1.	public class Solution {  
2.	    public int[] intersect(int[] nums1, int[] nums2) {          
3.	          
4.	        List<Integer> list = new ArrayList<Integer>();  
5.	        List<Integer> interList = new ArrayList<Integer>();  
6.	          
7.	        for(int num:nums1) {  
8.	            list.add(num);  
9.	        }  
10.	          
11.	        for(int i=0;i<nums2.length;i++) {  
12.	            if(list.contains(nums2[i])) {  
13.	                interList.add(nums2[i]);  
14.	                list.remove(list.indexOf(nums2[i]));  
15.	            }  
16.	        }  
17.	          
18.	        int[] ret = new int[interList.size()];  
19.	        int cnt = 0;  
20.	        for(int num:interList) {  
21.	            ret[cnt++] = num;  
22.	        }  
23.	          
24.	        return ret;  
25.	    }  
26.	}  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值