《七月集训》第二十六天 并查集

Crazy_DM 2022-07-27 19:23:01

面试题17.07.婴儿名字

解题思路:

1.并查集就是通过某些关系把原本散乱的点放入同一个集合中,一个集合只有一个相同的父节点。这么看的话,新生婴儿的名字有的是可以放入同一个集合中的,因此这题我们使用并查集来解决。

2.我们将名字映射到一个数字中放在一个unorder_map,将名字对应的婴儿数量放入另一个u_m中。因为名字映射到数字中,我们可以用一个整型数组来代表并查集,数组元素放着该节点的父节点的ID

3.当我们进行完并查集的init,find, merge操作后统计有多少个连通分量,连通分量的总和是多少(不断累加),连通分量最小的字典序是谁(不断修改为集合中的最小字典序)

class Solution {
public:
    int fa[100010], groupSum[100010];
    string groupName[100010];
    unordered_map<string, int> name2Fre; //这个名字的数量
    unordered_map<string, int> name2Id;  //这个名字映射的Id 
    
    void init(int n) {
        for(int i = 1; i <= n; ++i) {
            fa[i] = i;
        }
    }
    int find(int x) {
        return (x == fa[x]) ? x : (fa[x] = find(fa[x]));
    }
    void merge(int i, int j) {
        int x = find(i), y = find(j);

        if(x == y) return;
        else {
            fa[x] = y;
        }
    } 

    string int2string(int i) {
        if(!i) return "0";
        string str = to_string(i);
        return str;
    }


    vector<string> trulyMostPopular(vector<string>& names, vector<string>& synonyms) {
        int idFrom0 = 0;
        for(int i = 0; i < names.size(); ++i) {
            int fre = 0, flag = 0;
            string name = "";
            for(int j = 0; j < names[i].size(); ++j) {
                if(names[i][j] == '(') {
                    flag = 1;
                    //continue;
                }
                else if(flag == 1 && names[i][j] != ')') {
                    fre *= 10;
                    fre += names[i][j] - '0';
                }
                else if(flag == 0){
                    name += names[i][j];
                }
            }

            name2Fre[name] = fre;
            name2Id[name] = ++idFrom0;
        }
        init(100010 - 1);

        for(int i = 0; i < synonyms.size(); ++i) {
            string name1, name2;
            int flag = 0;
            for(int j = 0; j < synonyms[i].size(); ++j) {
                if(synonyms[i][j] == ',') flag = 1;
                else if(flag && synonyms[i][j] != ')') name2 += synonyms[i][j];
                else if(!flag && synonyms[i][j] != '(') name1 +=synonyms[i][j];
            }

            if(name2Id[name1] == 0) {
                name2Fre[name1] = 0;
                name2Id[name1] = ++idFrom0;
            }
            if(name2Id[name2] == 0) {
                name2Fre[name2] = 0;
                name2Id[name2] = ++idFrom0;
            }
            merge(name2Id[name1], name2Id[name2]);
        }
        
        for(auto iter = name2Fre.begin(); iter != name2Fre.end(); ++iter) {
            int id = name2Id[iter -> first]; //名字
            int faId = find(id); //父节点编号
            if(groupName[faId] == "" || iter -> first < groupName[faId]) { //只有一个父节点,所以其他节点不会被更新
                groupName[faId] = iter -> first;
            }
            groupSum[faId] += name2Fre[iter -> first]; //数量
        }

        vector<string> ret;
        for(int i = 1; i <= idFrom0; ++i) {
            if(groupName[i] != "")
                ret.push_back(groupName[i] + "(" + int2string(groupSum[i]) + ")");
        }
        return ret;
    }
};

 

...全文
82 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
CSDN-Ada助手 2023-01-13
  • 打赏
  • 举报
回复
您可以前往 CSDN问答-Java 发布问题, 以便更快地解决您的疑问
内容概要:本文围绕“基于共享储能服务的智能楼宇双层优化配置”展开研究,提出了一种结合上层共享储能配置优化与下层楼宇内部能源调度优化的双层协同模型,通过Matlab代码实现,旨在提升智能楼宇在复杂能源环境下的运行效率与经济性。研究充分考虑光伏出力、负荷需求等不确定性因素,引入多维核密度估计、场景生成与削减等技术进行不确定性建模,并融合需求响应、微电网调度等先进理念,实现了对综合能源系统中储能资源的高效配置与动态调控,具有较强的理论深度与工程应用价值。; 适合人群:具备电力系统、可再生能源、优化算法或综合能源系统等相关背景,从事科研、工程应用或课题研究的研发人员、研究生及高年级本科生。; 使用场景及目标:①应用于智能楼宇、园区微电网、虚拟电厂等场景中的储能规划与运行优化;②支撑高水平学术论文(如EI/SCI)的复现、课题申报、毕业设计及实际项目的双层优化建模与求解实践。; 阅读建议:建议结合提供的Matlab代码进行实操演练,重点理解双层优化架构的设计逻辑、求解策略(如Benders分解、主从博弈等)及不确定性处理方法,同时可参考文中关联技术(如场景生成、需求响应)拓展研究思路与应用场景。

64,204

社区成员

发帖
与我相关
我的任务
社区描述
学习「 算法 」的捷径就是 「 题海战略 」,社区由「 夜深人静写算法 」作者创建,三年ACM经验,校集训队队长,亚洲区域赛金牌,世界总决赛选手。社区提供系统的训练,答疑解惑,面试经验,大厂内推等机会
社区管理员
  • 英雄哪里出来
  • 芝麻粒儿
  • Amy卜bo皮
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

QQ群:480072171

英雄算法交流 8 群

 

试试用AI创作助手写篇文章吧