哈希(4) - 求两个链表的交集以及并集

目录

1.简单方法

2.使用归并排序

3.使用哈希


给定两个链表,求它们的交集(intersection)以及并集(union)。用于输出的list中的元素顺序可不予考虑。
例子:
输入下面两个链表:
    list1: 10->15->4->20
    list2: 8->4->2->10
输出链表:
    交集list: 4->10
    并集list: 2->8->20->4->15->10

1.简单方法

可以参考链表系列中的"链表操作 - 求两个链表的交集(intersection)以及并集(union)"

2.使用归并排序

可以参考链表系列中的"链表操作 - 求两个链表的交集(intersection)以及并集(union)"

3.使用哈希

calculateUnion (list1, list2),求链表的并集的算法:
将result list初始化为NULL,然后创建一个空的哈希表。依次遍历这两个链表,对于其中的每个元素,在哈希表中进行查找。如果元素不在哈希表中,则将其插入到result list中,并插入到哈希表中。如果元素已经存在于哈希表中,则忽略它。

calculateIntersection (list1, list2),求链表的交集的算法:
将result list初始化为NULL,然后创建一个空的哈希表。 遍历list1, 对于其中的每个元素,将其插入到哈希表中。然后遍历list2, 对于其中的每个元素,在哈希表中进行查找。如果元素已经存在于哈希表中,则插入到result list中。如果元素不在哈希表中,则忽略它。

上面的这两个方法,即使list中存在重复的元素,也能处理。
时间复杂度:方法3的时间复杂度取决于所使用的哈希方法,以及输入链表中的元素分布。在实际的情况中,方法3可能比前面的两种方法更好。

代码如下:

#include<iostream>
#include<algorithm>
#include<map>
#include<list>

void calculateUnion(const std::list<int>& list1, const std::list<int>& list2, std::list<int>& outputResult) {
    std::map< int, bool> tmp;
    for (auto iter : list1) {
        if (tmp.find(iter) == tmp.end())
            tmp.insert(std::make_pair(iter, true));
    }
    for (auto iter : list2) {
        if (tmp.find(iter) == tmp.end())
            tmp.insert(std::make_pair(iter, true));
    }
    //convert map to list
    for (auto iter : tmp) {
        if (iter.second)
            outputResult.push_back(iter.first);
    }
}

void calculateIntersection(const std::list<int>& list1, const std::list<int>& list2, std::list<int>& outputResult) {
    std::map< int, bool> tmp;
    for (auto iter : list1) {
        tmp.insert(std::make_pair(iter, false));
    }
    for (auto iter : list2) {
        if (tmp.find(iter) != tmp.end())
            outputResult.push_back(iter);
    }
}

int main() {
    //list1: 10->15->4->20
    //list2:  8->4->2->10
    std::list< int> list1, list2, result;
    list1.push_back(10);
    list1.push_back(15);
    list1.push_back(4);
    list1.push_back(20);

    list2.push_back(8);
    list2.push_back(4);
    list2.push_back(2);
    list2.push_back(10);

    calculateUnion(list1, list2, result);
    std::cout << "union result: \n";
    std::for_each(result.begin(), result.end(), [](const int& value) {
        std::cout << value << " ";
        });

    result.clear();
    calculateIntersection(list1, list2, result);
    std::cout << "\nintersection result: \n";
    std::for_each(result.begin(), result.end(), [](const int& value) {
        std::cout << value << " ";
        });
    std::cout << std::endl;

    return 0;
}

运行结果:
union result:
2 4 8 10 15 20
intersection result:
4 10

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值