代码随想录刷题-哈希表-两个数组的交集

两个数组的交集

本节对应代码随想录中:代码随想录,讲解视频:学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集_哔哩哔哩_bilibili

习题

题目链接:349. 两个数组的交集 - 力扣(LeetCode)

给定两个数组 nums1 和 nums2 ,返回它们的交集。输出结果中的每个元素一定是唯一的。我们可以不考虑输出结果的顺序。

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

示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

我的解法

这题我是用的上题进阶解法用到的 unordered_map,只不过由于取交集,如果有重复的只输出一次即可。所以我在存的时候让 nums1对应的次数都为1,遍历 nums2时,如果次数为1则 push_back 并且次数+1,这样就不会重复输出。

class Solution {
   public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_map<int, int> hash;
        vector<int> res;
        // 不同的数只放一次
        for (int i = 0; i < nums1.size(); i++) {
            hash[nums1[i]] = 1;
        }
        for (int i = 0; i < nums2.size(); i++) {
            // 次数为1说明重叠,加1后后面就不会push_back同样的元素
            if (hash[nums2[i]] == 1) {
                res.push_back(nums2[i]);
                hash[nums2[i]]++;
            }
        }
        return res;
    }
};
  • 时间复杂度:O(m+n)。其中m为nums1的长度,n为nums2的长度。需要遍历两个数组来建立哈希表和查找重叠元素,时间复杂度为O(m+n)。
  • 空间复杂度:O(min(m,n))。哈希表中最多存储 min(m,n)个不同的元素,因此空间复杂度为 O(min(m,n))。

set 解法

这道题由于去重,所以其实用 set 更合适。

代码随想录中用了两个 set,一个遍历 nums1,另一个存放结果(这样结果就会去重)。但其实只用一个 set 即可,用一个 set 遍历 nums1后,再去遍历 nums2时,判断元素是否出现,若出现则 push_back 并且 erase 即删除这个元素。这样例如示例1中后面即使有重复的2,但我们在遍历第一个2进行 push_back 后就将 set 中的2删除了,遇到第二个2的时候其实就是找不到的状态了,所以就不会重复输出。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> nums_set(nums1.begin(), nums1.end());
        vector<int> res;
        for (int num : nums2) {
            // 如果nums_set包含num,则num是交集之一,加入结果并从集合中删除num
            if (nums_set.erase(num)) {
                res.push_back(num);
            }
        }
        return res;
    }
};
  • 时间复杂度:O(m+n)。其中m和n分别为nums1和nums2的长度。因为需要遍历nums1和nums2各一次,而unordered_set的查找和删除操作的时间复杂度都是常数级别的,所以总时间复杂度为O(m+n)。
  • 空间复杂度:O(min(m,n))。其中m和n分别为nums1和nums2的长度。因为需要使用unordered_set存储nums1中的元素,所以空间复杂度取决于nums1和nums2中较小的那个。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这道题目要求我们找出两个数组中不共有的元素。我们可以先将两个数组合并成一个新的数组,然后遍历这个新数组,找出只在其中一个数组中出现的元素即可。具体实现可以使用哈希表来记录每个元素出现的次数,然后再遍历一遍哈希表,找出只出现过一次的元素即可。 ### 回答2: 题目描述: 给定两个长度分别为 n 和 m 的数组 A 和 B。请你从 A 和 B 中各找出一个数,使得这两个数的差最小。(即找到 A 集合和 B 集合中的一对数,它们的差的绝对值最小) 思路分析: 此题需要我们进行一定的数学推导。我们假设我们的两个数组 A 和 B 都是从小到大排好序的,那么我们可以用两个指针 i 和 j 来代表 A 和 B。同时,我们可以设定一个变量minDiff用来存储当前最小的差值。我们把 A[0] 和 B[0] 的差值作为初始值存入minDiff,然后我们再用以下的方法来找到最小的差值: 1. 如果 A[i] 比 B[j] 小,那么我们就将 i++ 就可以找到一个更大的数; 2. 同理,如果 A[i] 比 B[j] 大,那么我们就将 j++ 就可以找到一个更大的数; 3. 如果它们相等,那么差值为0,直接返回即可。 代码实现: ```python def minDifference(A, B): i, j, minDiff = 0, 0, abs(A[0] - B[0]) while i < len(A) and j < len(B): diff = abs(A[i] - B[j]) if diff < minDiff: minDiff = diff if A[i] < B[j]: i += 1 else: j += 1 return minDiff ``` 时间复杂度:O(n+m),其中 n 和 m 分别代表了 A 和 B 的长度。 总结: 通过本题,我们可以看到双指针在数组有序的情况下是一种非常高效的算法。但是需要注意,这种算法并不局限于两个数组的问题,同样适用于单个数组中的问题。如果在解决问题时需要用到迭代或者数组,那么我们可以考虑一下双指针算法。 ### 回答3: 给定两个数组A和B,要求找出A和B中不共有的元素。 首先需要了解什么是两个数组共有的元素。两个数组共有的元素就是指同时出现在A和B中的元素,也就是交集部分。因此,不共有的元素就是指只出现在A或B中的元素,也就是并集中除去交集的元素。 一种简单的思路是先将A和B的交集求出来,然后用这个交集部分去除A和B的并集即可得到不共有的元素。 具体做法如下: 1. 定义一个新的数组C,用来存放A和B的交集部分。 2. 通过双重循环遍历数组A和B,如果某个元素在A和B中都出现过,则将其加入数组C中。 3. 定义一个新的数组D,用来存放A和B的并集部分。 4. 将数组A和B中的所有元素加入数组D中。 5. 遍历数组C,将数组D中与C中元素相同的元素删除。 6. 最终得到的数组D即为A和B中不共有的元素。 代码示例: ```python A = [1, 2, 3, 4, 5] B = [3, 4, 5, 6, 7] C = [] D = A + B #寻找交集 for i in A: for j in B: if i == j: C.append(i) #去除交集 for k in C: if k in D: D.remove(k) print(D) #输出结果为[1, 2, 6, 7] ``` 上述代码中,先定义了两个数组A和B,以及一个空数组C和一个合并了A和B的数组D。双重循环遍历A和B,如果某个元素在A和B中都出现过,则将其加入数组C中。再遍历数组C,将数组D中与C中元素相同的元素删除,最终得到的数组D即为A和B中不共有的元素。 需要注意的是,上述方法仅适用于两个数组的情况。如果要处理多个数组的情况,则需要先对所有数组求并集,然后再将所有数组交集部分从并集中删除,得到最终的不共有的元素数组

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值