当前位置: 首页 > news >正文

2023-02-20 leetcode-AccountsMerge

摘要:

记录对leetcode-AccountsMerge的反思

要求:

Given a list accounts, each element accounts[i] is a list of strings, where the first element 
accounts[i][0] is a name, and the rest of the elements are emails representing emails of the 
account.
 * 
Now, we would like to merge these accounts.  Two accounts definitely belong to the same person if 
there is some email that is common to both accounts.  Note that even if two accounts have the same 
name, they may belong to different people as people could have the same name.  A person can have 
any number of accounts initially, but all of their accounts definitely have the same name.
 * 
After merging the accounts, return the accounts in the following format: the first element of each 
account is the name, and the rest of the elements are emails in sorted order.  The accounts 
themselves can be returned in any order.
 * 
Example 1:
 * 
Input: 
accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], 
["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]]
Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'],  ["John", 
"johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]
 * 
Explanation: 
The first and third John's are the same person as they have the common email "johnsmith@mail.com".
The second John and Mary are different people as none of their email addresses are used by other 
accounts.
We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], 
['John', 'johnnybravo@mail.com'], 
['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted.
 * 
Note:
The length of accounts will be in the range [1, 1000].
The length of accounts[i] will be in the range [1, 10].
The length of accounts[i][j] will be in the range [1, 30].

数据结构相关:

  1. std::vector
  2. std::map
  3. std::unordered_map

题解:

题解一:

// Declare variables for accounts, mapping and result
vector<vector<string>> accounts;
unordered_map<string, string> mapping;
vector<vector<string>> result;// Add accounts to 'accounts'
// ...// Traverse accounts
for (auto &a : accounts) {// Take the first email address and consider it as the root string root = a[1];for (int i = 2; i < a.size(); i++) {// If current email is already present in map if (mapping.find(a[i]) != mapping.end())root = mapping[a[i]]; // Choose its parent else keep root // Make an entry for all those email address mapping[a[i]] = root;}
}// Create the necessary structure for result 
unordered_map<string, set<string>> mp;
for (auto &p : mapping) mp[p.second].insert(p.first);// Form the resultant vector
for (auto &pp : mp) {vector<string> emails(pp.second.begin(), pp.second.end());emails.insert(emails.begin(), pp.first);result.push_back(emails);
}return result;

题解二:

Bad Performance Solution


//Bad Performance Solution
class Solution_Time_Limit_Exceeded {
public:// We can orginze all relevant emails to a chain,// then we can use Union Find algorithm// Besides, we also need to map the relationship between name and email.vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) {unordered_map<string, string> emails_chains; // email chainsunordered_map<string, string> names; // names to email chains' head//initializationfor(int i = 0 ; i<accounts.size();i++) {auto& account = accounts[i];auto& name = account[0];for (int j=1; j<account.size(); j++) {auto& email = account[j];if ( names.find(email) == names.end() ) {emails_chains[email] = email;names[email] = name;}join(emails_chains, account[1], email);}}//reform the emailsunordered_map<string, set<string>> res;for( auto& acc : accounts ) {string e = find(emails_chains, acc[1]);res[e].insert(acc.begin()+1, acc.end());}//output the resultvector<vector<string>> result;for (auto pair : res) {vector<string> emails(pair.second.begin(), pair.second.end());emails.insert(emails.begin(), names[pair.first]);result.push_back(emails);}return result;}string find(unordered_map<string, string>& emails_chains,string email) {while( email != emails_chains[email] ){email = emails_chains[email];}return email;}bool join(unordered_map<string, string>& emails_chains,string& email1, string& email2) {string e1 = find(emails_chains, email1);string e2 = find(emails_chains, email2);if ( e1 != e2 )  emails_chains[e1] = email2;return e1 == e2;}
};

题解三:

Performance Tunning

//
// Performance Tunning
// -----------------
//
// The above algorithm need to do string comparison, it causes lots of efforts
// So, we allocated the ID for each email, and compare the ID would save the time.
//
// Furthermore, we can use the Group-Email-ID instead of email ID,
// this would save more time.
//
class Solution {
public:// We can orginze all relevant emails to a chain,// then we can use Union Find algorithm// Besides, we also need to map the relationship between name and email.vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) {unordered_map<string, int> emails_id; //using email ID for union findunordered_map<int, int> emails_chains; // email chainsunordered_map<int, string> names; // email id & name//initialization & joinfor(int i = 0 ; i<accounts.size();i++) {// using the account index as the emails group ID,// this could simplify the emails chain.emails_chains[i] = i;auto& account = accounts[i];auto& name = account[0];for (int j=1; j<account.size(); j++) {auto& email = account[j];if ( emails_id.find(email) == emails_id.end() ) {emails_id[email] = i;names[i] = name;}else {join( emails_chains, i, emails_id[email] );}}}//reform the emailsunordered_map<int, set<string>> res;for(int i=0; i<accounts.size(); i++) {int idx = find(emails_chains, i);res[idx].insert(accounts[i].begin()+1, accounts[i].end());}//output the resultvector<vector<string>> result;for (auto pair : res) {vector<string> emails( pair.second.begin(), pair.second.end() );emails.insert(emails.begin(), names[pair.first]);result.push_back(emails);}return result;}int find(unordered_map<int, int>& emails_chains, int id) {while( id != emails_chains[id] ){id = emails_chains[id];}return id;}bool join(unordered_map<int, int>& emails_chains, int id1, int id2) {int e1 = find(emails_chains, id1);int e2 = find(emails_chains, id2);if ( e1 != e2 )  emails_chains[e1] = e2;return e1 == e2;}
};

http://www.lryc.cn/news/14383.html

相关文章:

  • 中国高速公路行业市场规模及未来发展趋势
  • 佳能iC MF645CX彩色激光多功能打印机报E302-0001故障码检修
  • 加密越来越简单——用JavaScript实现数据加密和解密
  • 线程池的使用场景
  • 图像分割算法
  • 《mysql技术内幕:innodb存储引擎》笔记
  • windows与linux系统ntp服务器配置
  • html常用font-family设置字体样式
  • 数据库事务AICD以及隔离级别
  • (4)VScode之ssh基础配置
  • springcloud-1环境搭建、service provider
  • 光谱仪工作过程及重要参数定义
  • W800|iot|HLK-W800-KIT-PRO|AliOS|阿里云| |官方demo|学习(1):板载AliOS系统快速上手
  • 字节终面,一道Linux题难住我了
  • 三、NetworkX工具包实战2——可视化【CS224W】(Datawhale组队学习)
  • 【MySQL】MySQL 架构
  • Python日期时间模块
  • 学以致用——植物信息录入1.0(selenium+pandas+os+tkinter)
  • 什么是压敏电阻
  • Leetcode.901 股票价格跨度
  • vue入门(四)组件基础,$emits简单用法
  • VBA提高篇_27 OptionBOX_CheckBox_Frame_Image_VBA附加控件
  • STM32开发(11)----CubeMX配置独立看门狗(IWDG)
  • 医疗方案 | 星辰天合入选“2022智慧新医信优秀解决方案”
  • 【系统服务实战】tomcat服务的安装实战
  • 【图文详解】Unity存储游戏数据的几种方法
  • SESAM 安装教程
  • 语言文件操作
  • Java面试题--熔断和降级的区别
  • 阅读笔记5——深度可分离卷积