题目描述:
解题思路:构建一个key-value对,key为数组元素,value表示该元素在第几个集合中;
将所有的集合中的元素都拷贝到一个数组中,
根据元素排序,使得相同的元素都在一起,然后更改下标。
循环检测,直到没有可以更改的元素为止。
统计此时元素有几个下标,就是剩下了几个集合。
代码:
struct MyValue{ int val; int idx; MyValue(int v, int i):val(v), idx(i){ } }; static bool cmp(MyValue* t1, MyValue* t2){ return t1->val < t2->val; } bool check(vector<MyValue*> v, int& src){ for(int i=1; i<v.size(); ++i){ if(v[i]->val ==v[i-1]->val && v[i]->idx != v[i-1]->idx){ src = i; return true; } } return false; } int setUnion(vector<vector<int>> &sets) { // Write your code here if(sets.empty()) return 0; vector<MyValue*> v; for(int i=0; i<sets.size(); ++i){ for(int j=0; j<sets[i].size(); ++j){ MyValue* t = new MyValue(sets[i][j], i); v.push_back(t); } } sort(v.begin(), v.end(), cmp); for(int i=1; i<v.size(); ++i){ if(v[i]->val == v[i-1]->val && v[i]->idx != v[i-1]->idx){ int src = v[i]->idx; int des = v[i-1]->idx; for(int j=0; j<v.size(); ++j){ if(v[j]->idx == src) v[j]->idx = des; } } } int flag = -1; while(check(v, flag)){ int src = v[flag]->idx; int des = v[flag-1]->idx; for(int i=0; i<v.size(); ++i){ if(v[i]->idx == src){ v[i]->idx = des; } } } set<int> res; for(int i=0; i<v.size(); ++i){ res.insert(v[i]->idx); } return res.size(); }注意:此题有一个陷阱,例 [ [1,2,3] , [4,5,6] , [3,4] ] 该list在合并之后只剩一个集合。注意本来无法合并的两个集合因为第三个集合可以合并到一起。