【力扣-双指针】1、两个数组得交集II(350)

148 阅读1分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。

350. 两个数组的交集 II

题目描述

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

 

进阶

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

暴力法

class Solution1
{

private:
    vector<int> func(multiset<int> set1, multiset<int> set2, vector<int> nums)
    {
        // 记录最终得结果
        multiset<int> mset;
        
        // 遍历size较小的数组
        for (int i = 0; i < nums.size(); i++)
        {
            // 判断set中是否存在元素 nums[i]
            
            int n1 = set1.count(nums[i]);
            int n2 = set2.count(nums[i]);
            int n3 = mset.count(nums[i]);
            
            // 如果在两个数组中都存在
            if (n1 && n2)
            {
                // 判断记录的次数是否小于nums[i]在两个数组中出现的最小次数
                if (n3 < (n1 < n2 ? n1 : n2))
                {
                    mset.insert(nums[i]);
                }
            }
        }
        // 转换为 vector
        vector<int> result(mset.begin(), mset.end());
        return result;
    }

public:
    vector<int> intersect(vector<int> &nums1, vector<int> &nums2)
    {
        // 拷贝两个数组
        multiset<int> set1(nums1.begin(), nums1.end());
        multiset<int> set2(nums2.begin(), nums2.end());

        // 判断哪个数组较小
        if (nums1.size() <= nums2.size())
        {
            return func(set1, set2, nums1);
        }

        return func(set1, set2, nums2);
    }
};

排序+双指针法

class Solution
{
public:
    vector<int> intersect(vector<int> &nums1, vector<int> &nums2)
    {
        // 先对两个数组进行排序
        sort(nums1.begin(), nums1.end());
        sort(nums2.begin(), nums2.end());

        int idx1 = 0;
        int idx2 = 0;

        vector<int> result;
        
        // 遍历两个数组
        while (idx1 < nums1.size() && idx2 < nums2.size())
        {
            // 数组1的元素小于数组2的元素,将索引前移
            if (nums1[idx1] < nums2[idx2])
            {
                idx1++;
            }
            else if (nums1[idx1] == nums2[idx2])
            {
                // 记录结果
                result.push_back(nums1[idx1++]);
                idx2++;
            }
            else
            {
                // 数组2的元素较小,索引前移
                idx2++;
            }
        }

        return result;
    }
};