1061. 按字典序排列最小的等效字符串

题目:

思路:

【1】本质上和  990. 等式方程的可满足性 这题很相似,并交集的方式是最合理的,因为把所有ASCII码值大的字符替换为可以转换的值小的字符,所以并交集产生时候选择父节点需要注意一下,此外每个节点的对等比较其实都是指他们的顶级父节点的对等比较(这个是需要注意的,也就是为什么要取出他们的父节点)

代码展示:

//时间1 ms 击败 100%
//内存39.7 MB 击败 94%
class Solution {
    public String smallestEquivalentString(String s1, String s2, String baseStr) {
        int[] parent = new int[26];
        // 首先设置每个节点的父节点都是自己
        for (int i = 0; i < 26; i++) {
            parent[i] = i;
        }
        char[] chars1 = s1.toCharArray(), chars2 = s2.toCharArray();

        for (int i = 0; i <chars1.length; i++){
            // 取出他们当前的父节点(为什么要取出父节点)
            // 因为如果已经f->a , 那么现在又来一个 f->b , 我们想要的应该是 b->a,而不是a->b
            // 下面进行判断的时候 如果拿的不是父节点 而是F和B的话,就会把B放到了后面,进而导致 a->b 的出现
            // 这种不是我们想要的
            int index1 = find(parent,chars1[i] - 'a');
            int index2 = find(parent,chars2[i] - 'a');
            // 把值小的放到后面作为父节点
            if (index1>index2){
                union(parent, index1, index2);
            }else {
                union(parent,index2, index1);
            }
        }


        //获取按字典序排列最小的等价字符串
        StringBuffer buf = new StringBuffer();
        for (char ch : baseStr.toCharArray()){
            // 这里要找的也是能替代的该字符的价值最小的字符也就是他的最顶级父节点
            buf.append((char)('a'+find(parent,ch-'a')));
        }
        return buf.toString();
    }

    // 看代码可知,如果index2放的是值小的那么便是优先以字母值小的作为父节点
    public void union(int[] parent, int index1, int index2) {
        parent[find(parent, index1)] = find(parent, index2);
    }

    // 这里是核心的查找父节点的逻辑
    public int find(int[] parent, int index) {
        while (parent[index] != index) {
            // 这一步并不关键,因为他的主要作用是将层级差巨大的进行缩短
            // 如 f->b->c ,直接变为 f->c,这种形式,用于缩短查找,但没有也不影响结果
            parent[index] = parent[parent[index]];
            index = parent[index];
        }
        return index;
    }
}

 

posted @ 2023-08-22 17:43  忧愁的chafry  阅读(27)  评论(0编辑  收藏  举报