并查集之面试题 17.07. 婴儿名字

前言

并查集

一, 面试题 17.07. 婴儿名字

每年,政府都会公布一万个最常见的婴儿名字和它们出现的频率,也就是同名婴儿的数量。有些名字有多种拼法,例如,John 和 Jon 本质上是相同的名字,但被当成了两个名字公布出来。给定两个列表,一个是名字及对应的频率,另一个是本质相同的名字对。设计一个算法打印出每个真实名字的实际频率。注意,如果 John 和 Jon 是相同的,并且 Jon 和 Johnny 相同,则 John 与 Johnny 也相同,即它们有传递和对称性。

在结果列表中,选择 字典序最小 的名字作为真实名字。

示例:

输入:names = ["John(15)","Jon(12)","Chris(13)","Kris(4)","Christopher(19)"], synonyms = ["(Jon,John)","(John,Johnny)","(Chris,Kris)","(Chris,Christopher)"]
输出:["John(27)","Chris(36)"]
 

提示:

names.length <= 100000

二,解题思路

1, a和b是朋友, b和c是朋友,那a和c也是朋友。这就是典型并查集类型

所以这个题目是并查集类型的题目

2, 字典序

比较玩家的姓名

3,

三, 代码

#include <unordered_map>
#include <iostream>
#include <vector>

using namespace std;

#include <iostream>
#include <vector>

class Solution {
    
    
private:
    struct name_size
    {
    
    
        std::string name;
        int size;
    };
private:
    int getfriend(int * unoin_find, int v)
    {
    
    
        if (unoin_find[v] == v)
        {
    
    
            return v;
        }
        return unoin_find[v] = getfriend(&unoin_find[0], unoin_find[v]);
    }
public:
    void init(int *unoin_find, int size)
    {
    
    
        for (int i = 0; i < size; ++i)
        {
    
    
            unoin_find[i] = i;
        }
    }
    /**
     * 返回字典序最小的字符串
     * @param name1
     * @param name2
     * @return
     */
    std::string checkout_trie(std::string name1, std::string name2)
    {
    
    
        if (name1.size() >= name2.size())
        {
    
    
            for (int i = 0; i < name2.size(); ++i)
            {
    
    
                if (name1[i] < name2[i])
                {
    
    
                    return name1;
                }
                else if (name1[i] > name2[i])
                {
    
    
                    return name2;
                }
            }
            return name2;
        }
        else
        {
    
    
            for (int i = 0; i < name1.size(); ++i)
            {
    
    
                if (name1[i] < name2[i])
                {
    
    
                    return name1;
                }
                else if (name1[i] > name2[i])
                {
    
    
                    return name2;
                }
            }
            return name1;
        }
        return name1;
    }
    vector<string> trulyMostPopular(vector<string>& names, vector<string>& synonyms)
    {
    
    
        std::unordered_map<std::string, int> m_name_index;
        int unoin_find[names.size()+1];
        init(&unoin_find[0], names.size() +1);
        for (int j = 0; j < names.size(); ++j)
        {
    
    
            std::string name ;
            std::string num ;
            bool  name_num = false;
            int name_index = 0;
            for (int i = 0; i < names[j].size(); ++i)
            {
    
    
                if (names[j][i] == '(')
                {
    
    
                    name.append(names[j], 0, i);
                    name_index = i;
                    name_num = true;
                }
                if (name_num)
                {
    
    
                    if (names[j][i] == '(' || names[j][i] == ')')
                    {
    
    }
                    else
                    {
    
    

                        num.append(names[j], name_index+1, names[j].size());
                        num.erase(std::remove(num.begin(), num.end(), ')'), num.end());
                        break;
                    }
                }
            }
            m_name_map[j].name = name;
            m_name_map[j].size = atoi(num.c_str()) ;
            m_name_index[name] = j;
        }


        for (int j = 0; j < synonyms.size(); ++j)
        {
    
    
            std::string name1 ;
            std::string name2;
            int name1_index = 0;
            bool  name_num = false;

            for (int i = 2; i < synonyms[j].size(); ++i)
            {
    
    
                if (name1_index == 0 && synonyms[j][i] == ',')
                {
    
    
                    name1_index = i;
                    name1.append(synonyms[j], 1, i-1);

                }
                if (name1_index> 0)
                {
    
    
                    if (synonyms[j][i] == ',' || synonyms[j][i] == ')')
                    {
    
    }
                    else
                    {
    
    
                        name2.append(synonyms[j], name1_index+1, synonyms[j].size());
                        name2.erase(std::remove(name2.begin(), name2.end(), ')'), name2.end());
                        break;
                    }

                }
            }
            int v1;
            {
    
    
                auto iter =  m_name_index.find(name1);
                if (iter == m_name_index.end())
                {
    
    
                    continue;
                }
                v1 = getfriend(&unoin_find[0], m_name_index[name1]);
            }
            int v2;
            {
    
    
                auto iter =  m_name_index.find(name2);
                if (iter == m_name_index.end())
                {
    
    
                    continue;
                }
                v2 = getfriend(&unoin_find[0], m_name_index[name2]);
            }
            if (v1 < v2)
            {
    
    
                unoin_find[m_name_index[name2]] = v1;
                for (int w = 0; w < names.size(); ++w)
                {
    
    
                    if (unoin_find[w] == v2)
                    {
    
    
                        unoin_find[w] = v1;
                    }
                }

            }
            else if (v1 > v2)
            {
    
    
                unoin_find[m_name_index[name1]] = v1;
                for (int w = 0; w < names.size(); ++w)
                {
    
    
                    if (unoin_find[w] == v1)
                    {
    
    
                        unoin_find[w] = v2;
                    }
                }
            }

        }

        std::vector<name_size> ret(names.size());

        for (int i = 0; i < names.size(); ++i)
        {
    
    
            ret[unoin_find[i]].size += m_name_map[i].size;
            if (ret[unoin_find[i]].name.size() <1)
            {
    
    
                ret[unoin_find[i]].name = m_name_map[i].name;
            }
            else
            {
    
    
                ret[unoin_find[i]].name = checkout_trie(ret[unoin_find[i]].name, m_name_map[i].name);
            }

        }



        std::vector<std::string> new_ret;
        for (const name_size& value: ret )
        {
    
    
            if (value.size > 0)
            {
    
    
                std::string new_name = value.name;
                new_name.append("(");
                new_name.append(std::to_string(value.size));
                new_name.append(")");
                new_ret.push_back(new_name);
            }
        }

        return new_ret;
    }

    std::unordered_map<int, name_size> m_name_map;

};


时间复杂度O()
空间复杂度O()

总结

猜你喜欢

转载自blog.csdn.net/Poisx/article/details/112597582