LeetCode算法题350:两个数组的交集II(Intersection of Two Arrays II)

技术交流可以加:
本人微信:xcg852390212
本人qq:852390212
学习交流qq群1(已满): 962535112
学习交流qq群2: 780902027

两个数组的交集II

LeetCode中文

LeetCode英文

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

示例 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 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

解答

方法1

unordered_map无序哈希表)来建立nums1中字符和其出现个数之间的映射, 然后遍历nums2数组,如果当前字符在哈希表中的个数大于0,则将此字符加入结果中,然后哈希表的对应值自减1。

nums1的大小为m,数组nums2的大小为n

  • 时间复杂度:O(m + n)
  • 空间复杂度:O(max(m,n))

C++代码

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res;
        unordered_map<int,int> mp;
        
        for(auto a : nums1) ++mp[a];
        for(auto b : nums2)
        {
            if(mp[b] > 0)
            {
                res.push_back(b);
                --mp[b];
            }
        }
        
        return res;
    }
};

Python代码

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        dt = {}
        res = []
        for a in nums1:
            if a not in dt:
                dt[a] = 1
            else:
                dt[a] += 1
        for b in nums2:
            if b in dt and dt[b] > 0:
                res.append(b)
                dt[b] -= 1
        return res

优化空间:哈希表统计两数组中长度较小的那个数组的元素个数。

  • 时间复杂度:O(m + n)
  • 空间复杂度:O(min(m,n))

C++代码

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res;
        
        unordered_map<int,int> mp;
        
        if(nums1.size() > nums2.size())
        {
            //长度较小的数组拷贝到临时数组
            vector<int> tmp(nums2);
            nums2 = nums1;
            nums1 = tmp;
        }
        
        for(auto a : nums1) ++mp[a];
        for(auto b : nums2)
        {
            if(mp[b] > 0)
            {
                res.push_back(b);
                --mp[b];
            }
        }
        
        return res;
    }
};

方法2

先将nums1nums2排序(从小到大排序),定义两个指针p1p2分别从nums1nums2出发,处理情况如下:

  1. 如果nums1[p1] == nums2[p2],则将numns[p1]放入结果,同时++p1,++p2
  2. 否则,nums1[p1] < nums2[p2] ? ++p1 : ++p2

直到p1p2到达数组尾部。

nums1的大小为m,数组nums2的大小为n

  • 时间复杂度:O(m log m + n log n)
  • 空间复杂度:O(max(m,n))

C++代码

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        sort(nums1.begin(),nums1.end());
        sort(nums2.begin(),nums2.end());
        
        vector<int> res;
        int p1 = 0,p2 = 0;
        while(p1 < nums1.size() && p2 < nums2.size())
        {
            if(nums1[p1] == nums2[p2])
            {
                res.push_back(nums1[p1]);
                ++p1;
                ++p2;
            }
            else{
                nums1[p1] < nums2[p2] ? ++p1 : ++p2;
            }
        }
        
        return res;
    }
};

你可能感兴趣的:(算法题总结,LeetCode)