(哈希表 ) 349. 两个数组的交集 ——【Leetcode每日一题】

❓349. 两个数组的交集

难度:简单

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

示例 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] 也是可通过的

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

💡思路:

法一:排序+双指针

如果两个数组是有序的,则可以使用双指针的方法得到两个数组的交集。

  • 首先对两个数组进行排序
  • 然后使用两个指针遍历两个数组。可以预见的是加入答案的数组的元素一定是递增的;
  • 为了保证加入元素的唯一性,我们在向结果数组ans 添加元素时,要判断该元素是否已经存在(如果ans添加第一个元素时,不需要判断)。

法二:哈希表

输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的,根据哈希表的性质可以去重:

  • 首先将 num1 中的元素放到哈希表 s1 中;
  • 然后遍历 num2 中元素,如果 s1 中也存在,则保存到另一个哈希表 ans 中;
  • 最后哈希表 ans 就是所求交集,将结果集合转为数组。

🍁代码:(Java、C++)

法一:排序+双指针
Java

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int len1 = nums1.length, len2 = nums2.length;
        int[] ans = new int[Math.min(len1, len2)];
        int index1 = 0, index2 = 0, index = 0;
        while(index1 < len1 && index2 < len2){
            if(nums1[index1] == nums2[index2]){
                if(index == 0){
                    ans[index++] = nums1[index1];
                }else if(nums1[index1] != ans[index - 1]){
                    ans[index++] = nums1[index1];
                }
                index1++;
                index2++;
            }else if(nums1[index1] < nums2[index2]){
                index1++;
            }else{
                index2++;
            }
        }
        return Arrays.copyOfRange(ans, 0, index);
    }
}

C++

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        sort(nums1.begin(), nums1.end());
        sort(nums2.begin(), nums2.end());
        vector<int> ans;
        vector<int>::iterator ite1 = nums1.begin(), ite2 = nums2.begin();
        while(ite1 != nums1.end() && ite2 != nums2.end()){
            if(*ite1 == *ite2){
                if(ans.size() == 0){
                    ans.push_back(*ite1);
                }else if(*ite1 != ans.back()){
                    ans.push_back(*ite1);
                }
                ite1++;
                ite2++;
            }else if(*ite1 < *ite2){
                ite1++;
            }else{
                ite2++;
            }
        }
        return ans;
    }
};

法二:哈希表
Java

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> s1 = new HashSet<Integer>();
        Set<Integer> ans = new HashSet<Integer>();
        for(int num : nums1){
            s1.add(num);
        }
        for(int num: nums2){
            if(s1.contains(num)){
                ans.add(num);
            }
        }
        //将结果集合转为数组, 另外申请一个数组存放setRes中的元素,最后返回数组
        int[] arr = new int[ans.size()];
        int j = 0;
        for(int i : ans){
            arr[j++] = i;
        }
        
        return arr;
    }
}

C++

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> s(nums1.begin(), nums1.end());
        unordered_set<int> ans;
        for(int num : nums2){
            if(s.find(num) != s.end()){
                ans.insert(num);
            }
        }
        return vector<int>(ans.begin(), ans.end());;
    }
};
🚀 运行结果:

在这里插入图片描述

🕔 复杂度分析:
  • 时间复杂度:法一: O ( m   l o g m + n   l o g n ) O(m \ log m+n \ log n) O(m logm+n logn),其中 mn 分别是两个数组的长度。对两个数组排序的时间复杂度分别是 O ( m log ⁡ m ) O(m \log m) O(mlogm) O ( n log ⁡ n ) O(n \log n) O(nlogn),双指针寻找交集元素的时间复杂度是 O ( m + n ) O(m+n) O(m+n)。法二为: O ( m + n ) O(m + n) O(m+n)
  • 空间复杂度:法一: O ( l o g m + l o g n ) O( log m+ log n) O(logm+logn),其中 mn 分别是两个数组的长度 , 空间复杂度主要取决于排序使用的额外空间。法二为: O ( n ) O(n) O(n)n 为两数组长度的最小值。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注: 如有不足,欢迎指正!
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
要删除哈希表中一个指针数组的信息,需要执行以下步骤: 1. 找到要删除的指针数组所在的哈希桶。 2. 在该哈希桶中遍历指针数组,找到要删除的指针。 3. 删除指针,并将指针数组中该位置后面的指针依次向前移动。 4. 如果指针数组中只有一个指针,那么需要将该哈希桶从哈希表中删除。 具体实现代码如下: ```C++ // 定义哈希表节点结构体 struct Node { int key; // 哈希键值 int* ptrArray; // 指针数组 int size; // 指针数组大小 Node* next; // 下一个节点指针 }; // 哈希表删除指针数组信息函数 void deletePtrArray(Node* hashTable[], int hashSize, int key, int* ptr) { int index = key % hashSize; // 计算哈希桶索引 Node* p = hashTable[index]; // 找到哈希桶头节点 Node* pre = NULL; // 遍历哈希桶中的节点 while (p != NULL) { if (p->key == key && p->ptrArray != NULL) { // 找到指针数组 int* target = NULL; int i; for (i = 0; i < p->size; i++) { if (p->ptrArray[i] == ptr) { // 找到要删除的指针 target = &p->ptrArray[i]; break; } } if (target != NULL) { // 删除指针 for (; i < p->size - 1; i++) { p->ptrArray[i] = p->ptrArray[i + 1]; } p->size--; if (p->size == 0) { // 如果指针数组为空,则删除哈希桶 if (pre == NULL) { hashTable[index] = p->next; } else { pre->next = p->next; } delete[] p->ptrArray; delete p; } } break; } pre = p; p = p->next; } } ``` 调用该函数时,需要传入哈希表哈希表大小、要删除的键值和指针。函数会在哈希表中查找指定键值的哈希桶,并遍历该哈希桶中的节点,找到指定的指针数组。然后在指针数组中查找要删除的指针,并将其删除。如果指针数组中只剩下一个指针,那么需要将该哈希桶从哈希表中删除。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷酷的懒虫

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值