最大关联集合-LintCode

204 篇文章 0 订阅
本文探讨了如何解决最大关联集合的问题,其中每个元素都与其他元素有相关性。通过给出的ListA和ListB,找到互相关联的最大集合。举例说明了如何找到这样的集合,并指出解决方案在于代码实现。
摘要由CSDN通过智能技术生成

亚麻卖书,每本书都有与其关联性很强的书,给出ListA与ListB,表示ListA[i]与ListB[i]有关联,输出互相关联的最大集合。(输出任意顺序),题目保证只有一个最大的集合。

 注意事项
书籍的数量不会超过5000。

样例
给出ListA = [“abc”,”abc”,”abc”], ListB = [“bcd”,”acd”,”def”], 返回 [“abc”,”acd”,”bcd”,”dfe”]。

解释:
abc与bcd,acd,dfe均有关联,所以最大的集合就是全部书籍构成的集合。

给出 ListA = [“a”,”b”,”d”,”e”,”f”], ListB = [“b”,”c”,”e”,”g”,”g”], 返回[“d”,”e”,”g”,”f”]。

解释:
当前的集合有[a,b,c],[d,e,g,f],那么最大的集合是[d,e,g,f]

思路见代码

#ifndef C805_H
#define C805_H
#include<iostream>
#include<vector>
#include<string>
#include<map>
using namespace std;
class Solution {
public:
    /**
    * @param ListA: The relation between ListB's books
    * @param ListB: The relation between ListA's books
    * @return: The answer
    */
    vector<string> maximumAssociationSet(vector<string> &ListA, vector<string> &ListB) {
        // Write your code here
        vector<string> res;
        if (ListA.empty() || ListB.empty())
            return res;
        map<string, string> m;
        map<string, int> count;
        //m存放ListA,ListB中出现的所有的字符串,并初始化
        for (auto c : ListA)
        {
            if (m.find(c) == m.end())
                m[c] = c;
        }
        for (auto t : ListB)
        {
            if (m.find(t) == m.end())
                m[t] = t;
        }
        //对于每对有关联性的书籍,求其最高层的书籍,并进行合并
        for (int i = 0; i < ListA.size(); ++i)
        {
            string root1 = unionSearch(ListA[i], m);
            string root2 = unionSearch(ListB[i], m);
            if (root1 != root2)
                m[root1] = root2; 
        }
        //对m进行路径压缩
        for (auto &c : m)
        {
            c.second = unionSearch(c.first, m);
        }
        //存放最高层书籍,与这些书籍相关书籍的本数
        for (auto c : m)
        {
            count[c.second]++;
        }
        //计算与高层书籍相关的最大本书和最高层书籍的书名
        int max = INT_MIN;
        string str;
        for (auto p : count)
        {
            if (p.second >= max)
            {
                str = p.first;
                max = p.second;
            }
        }
        //根据书名找到相关书籍
        for (auto t : m)
        {
            if (t.second == str)
                res.push_back(t.first);
        }
        return res;
    }
    //找到root的最高层结点
    string unionSearch(string root, map<string, string> &m)
    {
        while (root != m[root])
        {
            m[root] = m[m[root]];
            root = m[root];
        }
        return root;
    }
};
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值