# 1061. Lexicographically Smallest Equivalent String {%hackmd theme-dark %} `s1 = "parker", s2 = "morris"` Reflexivity: 'a' == 'a'. Symmetry: 'a' == 'b' implies 'b' == 'a'. Transitivity: 'a' == 'b' and 'b' == 'c' implies 'a' == 'c'. s1[i] s2[i] has properies blow 0: p <-> m. m==p p==m aaa ocb parker morris parser makkek s3 ="parser" -> "makkek" // 1 <= string len <= 1000 // all lowercase char parker morris graph p: p a: a abc cde zzz -> zzz ```cpp= char union_find(unordered_map<char, char> &root, char c) { if (root[c] == c) { return c; } return union_find(root, root[c]); } string parser(string &s1, string &s2, string &s3) { unordered_map<char, char> root; // set char as it's own root for (char c = 'a'; c <= 'z'; c++) { root[c] = c; } // a: a // b: b // z: z // construct relationship for (int i = 0; i < s1.size(); i++) { char root1 = union_find(root, s1[i]); char root2 = union_find(root, s2[i]); if (root1 < root2) { root[root2] = root1; } else { root[root1] = root2; } } // Transitivity: 'a' == 'b' and 'b' == 'c' implies 'a' == 'c'. string res; for (auto c: s3) { res.push_back(union_find(root, c)); } return res; } ``` ``` p = {} def find(x): p.setdefault(x, x) if x != p[x]: p[x] = find(p[x]) return p[x] for i in range(len(s1)): gS1, gS2 = find(s1[i]), find(s2[i]) if gS1 == gS2: continue if ord(gS1) < ord(gS2): p[gS2] = gS1 else: p[gS1] = gS2 ``` ###### tags: `mock interview` `面試`