zoukankan      html  css  js  c++  java
  • 简单-350-两个数组的交集

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

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

    需要多次记录交集中的重复元素,倘若无此条件,只需用set即可。考虑到需要记录重复元素的出现次数,可以考虑hashmap;关于空间复杂度,主要考虑哈希表的空间,因此选择长度小的数组取哈希映射,数组值为key,出现次数为value。

    也可以考虑排序数组后,对两个数组迭代,双指针,空间复杂度小。为了节省空间,两种方法都可以将小数组作为目标输出数组,找到交集元素后给小数组从首位开始赋值。

    /*如果 nums1 元素个数大于 nums2,则交换数组元素。
    对于 nums1 的每个元素,添加到 HashMap m 中,如果元素已经存在则增加对应的计数。
    初始化 k = 0,记录当前交集元素个数。
    遍历数组 nums2:
    检查元素在 m 是否存在,若存在且计数为正:
    将元素拷贝到 nums1[k],且 k++。
    减少 m 中对应元素的计数。
    返回 nums1 前 k 个元素。
    时间复杂度:mathcal{O}(n + m)O(n+m)。其中 nn,mm 分别代表了数组的大小。
    空间复杂度:mathcal{O}(min(n, m))O(min(n,m)),我们对较小的数组进行哈希映射使用的空间。
    */
    public int[] intersect(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            return intersect(nums2, nums1);
        }
        HashMap<Integer, Integer> m = new HashMap<>();
        for (int n : nums1) {
            m.put(n, m.getOrDefault(n, 0) + 1);
        }
        int k = 0;
        for (int n : nums2) {
            int cnt = m.getOrDefault(n, 0);
            if (cnt > 0) {
                nums1[k++] = n;
                m.put(n, cnt - 1);
            }
        }
        return Arrays.copyOfRange(nums1, 0, k);
    }
    /*
    对数组 nums1 和 nums2 排序。
    初始化指针 i,j 和 k 为 0。
    指针 i 指向 nums1,指针 j 指向 nums2:
    如果 nums1[i] < nums2[j],则 i++。
    如果 nums1[i] > nums2[j],则 j++。
    如果 nums1[i] == nums2[j],将元素拷贝到 nums1[k],且 i++,j++,k++。
    返回数组 nums1 前 k 个元素。
    时间复杂度:mathcal{O}(nlog{n} + mlog{m})O(nlogn+mlogm)。其中 nn,mm 分别代表了数组的大小。我们对数组进行了排序然后进行了线性扫描。
    空间复杂度:O(1)O(1),我们忽略存储答案所使用的空间,因为它对算法本身并不重要。
    */
    public int[] intersect(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int i = 0, j = 0, k = 0;
        while (i < nums1.length && j < nums2.length) {
            if (nums1[i] < nums2[j]) {
                ++i;
            } else if (nums1[i] > nums2[j]) {
                ++j;
            } else {
                nums1[k++] = nums1[i++];
                ++j;
            }
        }
        return Arrays.copyOfRange(nums1, 0, k);
    }
  • 相关阅读:
    笨方法学python中执行argv提示ValueError: not enough values to unpack (expected 4, got 1)
    VMware workstation安装
    Redis bigkey分析
    MySQL drop table 影响及过程
    MySQL 大表硬连接删除
    ES elasticsearch 各种查询
    ES elasticsearch 各种聚合
    ES elasticsearch 聚合统计
    ES elasticsearch 实现 count单字段,分组取前多少位,以地理位置中心进行统计
    MySQL行溢出、varchar最多能存多少字符
  • 原文地址:https://www.cnblogs.com/faded828x/p/13122115.html
Copyright © 2011-2022 走看看