边学边记录,希望有所进步。
附547题朋友圈解法:
class Solution {
public:
int FindAndUpdateFather(vector<int>& fathers, int i)
{
if (fathers[i] == i) {
return i;
}
// key2, 找老大,边找边更新
return (fathers[i] = FindAndUpdateFather(fathers, fathers[i]));
}
int findCircleNum(vector<vector<int>>& M) {
int totalNum = M.size();
vector<int> fathers(totalNum, 0);
for (int i = 0; i < totalNum; i++) {
fathers[i] = i; // 初始化,大家的老大都是自己
}
for (int i = 0; i < totalNum; i++) {
for (int j = i + 1; j < totalNum; j++) {
if (M[i][j] == 0) {
continue;
}
// key3,合并老大
int fatheri = FindAndUpdateFather(fathers, i);
int fatherj = FindAndUpdateFather(fathers, j);
if (fatheri != fatherj) {
fathers[fatheri] = fatherj;
}
}
}
int count = 0;
for (int i = 0; i < totalNum; i++) {
if (fathers[i] == i) {
count++;
}
}
return count;
}
};
附684. 冗余连接解法:
class Solution {
public:
int FindRoot(vector<int>& roots, int idx)
{
if (roots[idx] == idx) {
return idx;
}
return (roots[idx] = FindRoot(roots, roots[idx]));
}
vector<int> findRedundantConnection(vector<vector<int>>& edges) {
int totalNum = edges.size();
vector<int> roots(totalNum + 1, 0);
for (int i = 0; i < totalNum; i++) {
roots[i] = i;
}
int redundantIdx = 0;
for (int i = 0; i < totalNum; i++) {
int root0 = FindRoot(roots, edges[i][0]);
int root1 = FindRoot(roots, edges[i][1]);
if (root0 == root1) {
redundantIdx = i; // record and try update the last redundant idx
} else { // (root0 != root1)
roots[root0] = root1; // merge
}
}
return edges[redundantIdx];
}
};
附200. 岛屿数量解法:
class Solution {
public:
int FindRoot(vector<int>& roots, int idx) {
if (roots[idx] == idx) {
return idx;
}
return (roots[idx] = FindRoot(roots, roots[idx]));
}
void TryMerge(vector<int>& roots, int i, int j, int& count) {
int rooti = FindRoot(roots, i);
int rootj = FindRoot(roots, j);
if (rooti != rootj) {
roots[rooti] = rootj;
count--; // key1
}
}
int numIslands(vector<vector<char>>& grid) {
int hnum = grid.size();
if (hnum == 0) {
return 0;
}
int lnum = grid[0].size();
vector<int> roots;
int count = 0;
for (int i = 0; i < hnum; i++) {
for (int j = 0; j < lnum; j++) {
if (grid[i][j] == '1') {
roots.push_back(i * lnum + j); // init
count++; // key1
} else {
roots.push_back(-1);
}
}
}
for (int i = 0; i < hnum; i++) {
for (int j = 0; j < lnum; j++) {
if (grid[i][j] == '0') {
continue;
}
if ((i - 1 >= 0) && grid[i - 1][j] == '1') {
TryMerge(roots, (i - 1) * lnum + j, i * lnum + j, count); // key2
}
if ((i + 1 < hnum) && grid[i + 1][j] == '1') {
TryMerge(roots, (i + 1) * lnum + j, i * lnum + j, count); // key2
}
if ((j - 1 >= 0) && grid[i][j - 1] == '1') {
TryMerge(roots, i * lnum + j - 1, i * lnum + j, count); // key2
}
if ((j + 1 < lnum) && grid[i][j + 1] == '1') {
TryMerge(roots, i * lnum + j + 1, i * lnum + j, count); // key2
}
}
}
return count;
}
};
#include
#include
class Solution {
public:
int FindRoot(vector<int>& roots, int idx)
{
if (roots[idx] == idx) {
return idx;
}
return (roots[idx] = FindRoot(roots, roots[idx]));
}
bool areSentencesSimilarTwo(vector<string>& words1, vector<string>& words2, vector<vector<string>>& pairs)
{
unordered_map<string, int> mymap; // key1
int hnum = pairs.size();
int lnum = 0;
if (hnum != 0) {
lnum = pairs[0].size();
}
string it;
int cnt = 0;
vector<int> roots;
// Init && string->int
for (int i = 0; i < hnum; i++) {
for (int j = 0; j < lnum; j++) {
it = pairs[i][j];
if (mymap.find(it) == mymap.end()) {
mymap[it] = cnt;
roots.push_back(cnt);
cnt++;
}
}
}
// merge
for (int i = 0; i < hnum; i++) {
int root1 = FindRoot(roots, mymap.at(pairs[i][0]));
int root2 = FindRoot(roots, mymap.at(pairs[i][1]));
if (root1 != root2) {
roots[root1] = root2;
}
}
if (words1.size() != words2.size()) {
return false;
}
for (int i = 0; i < words1.size(); i++) {
if (words1[i] == words2[i]) {
continue;
}
if (mymap.find(words1[i]) == mymap.end() || mymap.find(words2[i]) == mymap.end()) {
return false;
}
int root1 = FindRoot(roots, mymap.at(words1[i]));
int root2 = FindRoot(roots, mymap.at(words2[i]));
if (root1 != root2) {
return false;
}
}
return true;
}
};
typedef struct {
int value;
int i;
int j;
} Node;
bool Cmp(const Node a, const Node b)
{
return (a.value > b.value);
}
class Solution {
public:
int FindRoot(vector<int>& roots, int idx)
{
if (roots[idx] == idx) {
return idx;
}
return (roots[idx] = FindRoot(roots, roots[idx]));
}
void Merge(vector<int>& roots, int idx1, int idx2)
{
int root1 = FindRoot(roots, idx1);
int root2 = FindRoot(roots, idx2);
if (root1 == root2) {
return;
}
roots[root1] = root2;
}
void myprint(vector<int>& roots)
{
for (int i = 0; i < roots.size(); i++) {
printf("roots[%d] = %d ", i, roots[i]);
}
printf("\n");
}
vector<Node> MySort(vector<Node>& a)
{
sort(a.begin(), a.end(), Cmp);
return a;
}
int maximumMinimumPath(vector<vector<int>>& A)
{
int hnum = A.size();
if (hnum == 0) {
return 0;
}
int lnum = A[0].size();
vector<Node> a;
Node node;
for (int i = 0; i < hnum; i++) {
for (int j = 0; j < lnum; j++) {
node.value = A[i][j];
node.i = i;
node.j = j;
a.push_back(node);
}
}
MySort(a);
int totalNum = hnum * lnum;
vector<int> roots;
for (int i = 0; i < totalNum; i++) {
roots.push_back(i); // init
}
set<int> s;
int beginIdx = 0;
int endIdx = 0;
for (int i = 0; i < totalNum; i++) {
if (a[i].i == 0 && a[i].j == 0) {
beginIdx = i;
}
if (a[i].i == hnum - 1 && a[i].j == lnum - 1) {
endIdx = i;
}
}
s.insert(0);
s.insert(totalNum - 1);
int outValue = A[0][0] < A[hnum - 1][lnum - 1] ? A[0][0] : A[hnum - 1][lnum - 1];
for (int i = 0; i < totalNum; i++) {
int x = a[i].i;
int y = a[i].j;
if (x == 0 && y == 0) {
continue;
}
if (x == hnum - 1 && y == lnum - 1) {
continue;
}
if (outValue > a[i].value) {
outValue = a[i].value;
}
s.insert(x * lnum + y);
if ((x - 1 >= 0) && (s.find((x - 1) * lnum + y) != s.end())) {
Merge(roots, x * lnum + y, (x - 1) * lnum + y);
}
if ((x + 1 < hnum) && (s.find((x + 1) * lnum + y) != s.end())) {
Merge(roots, x * lnum + y, (x + 1) * lnum + y);
}
if ((y - 1 >= 0) && (s.find(x * lnum + y - 1) != s.end())) {
Merge(roots, x * lnum + y, x * lnum + y - 1);
}
if ((y + 1 < lnum) && (s.find(x * lnum + y + 1) != s.end())) {
Merge(roots, x * lnum + y, x * lnum + y + 1);
}
int rootBegin = FindRoot(roots, 0);
int rootEnd = FindRoot(roots, totalNum - 1);
if (rootBegin == rootEnd) {
break;
}
}
return outValue;
}
};
2) 按value从小到大进行排序;
3) 初始化并查集;此时并查集的总root数totalRootNum为N----关键;
4) 将node逐个取出,查看h,l的root是不是相同,若不同则merge并且totalRootNum--;
5) 若totalRootNum减少到1则break结束;
typedef struct {
int value;
int h;
int l;
} Node;
bool Cmp(Node a, Node b)
{
return a.value < b.value; // 从小到大
}
class Solution {
public:
void MySort(vector<Node>& A)
{
sort(A.begin(), A.end(), Cmp);
}
int FindRoot(vector<int>& roots, int i)
{
if (roots[i] == i) {
return i;
}
return (roots[i] = FindRoot(roots, roots[i]));
}
int minimumCost(int N, vector<vector<int>>& connections) {
vector<int> roots;
for (int i = 0; i < N; i++) {
roots.push_back(i); // init
}
Node node;
vector<Node> A;
for (int i = 0; i < connections.size(); i++) {
node.value = connections[i][2];
node.h = connections[i][0] - 1;
node.l = connections[i][1] - 1;
A.push_back(node);
}
MySort(A);
int totalRootNum = N;
int totalValue = 0;
for (int i = 0; i < A.size(); i++) {
int root1 = FindRoot(roots, A[i].h);
int root2 = FindRoot(roots, A[i].l);
if (root1 == root2) {
continue;
}
roots[root1] = root2; // merge
totalRootNum--; // key: 每次merge后就少一个root,直到为1则退出;
totalValue += A[i].value;
if (totalRootNum <= 1) {
break;
}
}
if (totalRootNum <= 1) {
return totalValue;
}
return -1;
}
};
class Solution {
public:
int FindRoot(vector<int>& roots, int i)
{
if (roots[i] == i) {
return i;
}
return (roots[i] = FindRoot(roots, roots[i]));
}
bool validTree(int n, vector<vector<int>>& edges) {
vector<int> roots;
for (int i = 0; i < n; i++) {
roots.push_back(i); // init
}
int rootsNum = n;
for (int i = 0; i < edges.size(); i++) {
int root1 = FindRoot(roots, edges[i][0]);
int root2 = FindRoot(roots, edges[i][1]);
if (root1 == root2) {
return false;
}
roots[root1] = root2; // merge
rootsNum--; // key
}
if (rootsNum == 1) {
return true;
}
return false;
}
};
class Solution {
public:
int Find(vector<int>& roots, int i)
{
if (roots[i] == i) {
return i;
}
return (roots[i] = Find(roots, roots[i]));
}
string smallestEquivalentString(string A, string B, string S)
{
unordered_map<char, int> m;
for (char i = 'a'; i <= 'z'; i++) {
m[i] = i - 'a';
}
vector<int> roots;
for (int i = 0; i <= ('z' - 'a'); i++) {
roots.push_back(i);
}
for (int i = 0; i < A.size(); i++) {
int root1 = Find(roots, m[A[i]]);
int root2 = Find(roots, m[B[i]]);
if (root1 == root2) {
continue;
}
// merge
if (root1 < root2) {
roots[root2] = root1;
} else {
roots[root1] = root2;
}
}
string out = "";
for (int i = 0; i < S.size(); i++) {
int rootIdx = Find(roots, m[S[i]]);
out += (rootIdx + 'a');
}
return out;
}
};
class Solution {
public:
int Find(vector<int>& roots, int i)
{
if (roots[i] == i) {
return i;
}
return (roots[i] = Find(roots, roots[i]));
}
int countComponents(int n, vector<vector<int>>& edges) {
vector<int> roots;
for (int i = 0; i < n; i++) {
roots.push_back(i);
}
int totalNum = n;
for (int i = 0; i < edges.size(); i++) {
int root1 = Find(roots, edges[i][0]);
int root2 = Find(roots, edges[i][1]);
if (root1 == root2) {
continue;
}
roots[root1] = root2;
totalNum--;
}
return totalNum;
}
};