← All problems

1061. Lexicographically Smallest Equivalent String

MediumOpen on LeetCodeProblem statement

Problem Statement

1061. Lexicographically Smallest Equivalent String

Medium


You are given two strings of the same length s1 and s2 and a string baseStr.

We say s1[i] and s2[i] are equivalent characters.

Equivalent characters follow the usual rules of any equivalence relation:

For example, given the equivalency information from s1 = "abc" and s2 = "cde", "acd" and "aab" are equivalent strings of baseStr = "eed", and "aab" is the lexicographically smallest equivalent string of baseStr.

Return the lexicographically smallest equivalent string of baseStr by using the equivalency information from s1 and s2.

 

Example 1:

Input: s1 = "parker", s2 = "morris", baseStr = "parser"
Output: "makkek"
Explanation: Based on the equivalency information in s1 and s2, we can group their characters as [m,p], [a,o], [k,r,s], [e,i].
The characters in each group are equivalent and sorted in lexicographical order.
So the answer is "makkek".

Example 2:

Input: s1 = "hello", s2 = "world", baseStr = "hold"
Output: "hdld"
Explanation: Based on the equivalency information in s1 and s2, we can group their characters as [h,w], [d,e,o], [l,r].
So only the second letter 'o' in baseStr is changed to 'd', the answer is "hdld".

Example 3:

Input: s1 = "leetcode", s2 = "programs", baseStr = "sourcecode"
Output: "aauaaaaada"
Explanation: We group the equivalent characters in s1 and s2 as [a,o,e,r,s,c], [l,p], [g,t] and [d,m], thus all letters in baseStr except 'u' and 'd' are transformed to 'a', the answer is "aauaaaaada".

 

Constraints:

Java

Source file
class Solution {
    private class UnionFind {
        int[] root;

        UnionFind(int size) {
            root = new int[size];
            for (int i = 0; i < size; i++)
                root[i] = i;
        }

        int find(int x) {
            if (x == root[x])
                return x;
            return find(root[x]);
        }

        void union(int x, int y) {
            int rootX = find(x);
            int rootY = find(y);
            if (rootX != rootY) {
                if (rootX < rootY)
                    root[rootY] = rootX;
                else
                    root[rootX] = rootY;
            }
        }
    }

    public String smallestEquivalentString(String s1, String s2, String baseStr) {
        int n = s1.length(), len = baseStr.length();
        UnionFind uf = new UnionFind(26);
        for (int i = 0; i < n; i++) {
            int c1 = s1.charAt(i) - 'a', c2 = s2.charAt(i) - 'a';
            uf.union(c1, c2);
        }
        char[] cs = baseStr.toCharArray();
        for (int i = 0; i < len; i++)
            cs[i] = (char) ('a' + uf.find(cs[i] - 'a'));
        return new String(cs);
    }
}