Algorithm - Union-Find Problems

이소라·2022년 10월 21일
0

Algorithm

목록 보기
27/77

LeetCode Problem : Find if Path Exists in Graph

  • There is a bi-directional graph with n vertices, where each vertex is labeled from 0 to n - 1 (inclusive). The edges in the graph are represented as a 2D integer array edges, where each edges[i] = [ui, vi] denotes a bi-directional edge between vertex ui and vertex vi. Every vertex pair is connected by at most one edge, and no vertex has an edge to itself.

  • You want to determine if there is a valid path that exists from vertex source to vertex destination.

  • Given edges and the integers n, source, and destination, return true if there is a valid path from source to destination, or false otherwise.

    • Constraints
      • 1 <= n <= 2 * (10^5)
      • 0 <= edges.length <= 2 * (10^5)
      • edges[i].length == 2
      • 0 <= ui, vi <= n - 1
      • ui != vi
      • 0 <= source, destination <= n - 1
      • There are no duplicate edges.
      • There are no self edges.
  • Example 1

    • Input: n = 3, edges = [[0,1],[1,2],[2,0]], source = 0, destination = 2
    • Output: true
    • Explanation: here are two paths from vertex 0 to vertex 2 :
      • 0 → 1 → 2
      • 0 → 2
  • Example 2

    • Input: n = 6, edges = [[0,1],[0,2],[3,5],[5,4],[4,3]], source = 0, destination = 5
    • Output: false
    • Explanation: There is no path from vertex 0 to vertex 5.

Solution

var validPath = function(n, edges, source, destination) {
    const parent = [];
    
    for (let i = 0; i < n; i++) {
        parent[i] = i;
    }
    
    edges.forEach(([node1, node2]) => {
        unionParent(parent, node1, node2);
    });
    
    const result = findParent(parent, source, destination); 
    
    function getParent(parent, x) {
        if (parent[x] === x) return x;
        return parent[x] = getParent(parent, parent[x]);
    }

    function unionParent(parent, a, b) {
        a = getParent(parent, a);
        b = getParent(parent, b);
        a < b ? parent[b] = a : parent[a] = b;
    }

    function findParent(parent, a, b) {
      a = getParent(parent, a);
      b = getParent(parent, b);
      return a === b;
}
    
    return result;
};



Problem 1061. Lexicographically Smallest Equivalent String

  • 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.

    • For example, if s1 = "abc" and s2 = "cde", then we have 'a' == 'c', 'b' == 'd', and 'c' == 'e'.
  • Equivalent characters follow the usual rules of any equivalence relation:

    • Reflexivity: 'a' == 'a'.
    • Symmetry: 'a' == 'b' implies 'b' == 'a'.
    • Transitivity: 'a' == 'b' and 'b' == 'c' implies 'a' == 'c'.
  • 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.

Examples

  • 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

  • 1 <= s1.length, s2.length, baseStr <= 1000
  • s1.length == s2.length
  • s1, s2, and baseStr consist of lowercase English letters.

Solution

/**
 * @param {string} s1
 * @param {string} s2
 * @param {string} baseStr
 * @return {string}
 */
var smallestEquivalentString = function(s1, s2, baseStr) {
    const uf = new UnionFind();
    let result = '';

    for (let i = 0; i < s1.length; i++) {
        uf.unite(s1[i], s2[i]);
    }

    for (const letter of baseStr) {
        result += uf.find(letter);
    }

    return result;
};

class UnionFind {
    constructor() {
        this.parents = new Map();
    }

    find(a) {
        if (!this.parents.has(a)) {
            this.parents.set(a, a);
        } else if (this.parents.get(a) !== a) {
            this.parents.set(a, this.find(this.parents.get(a)));
        }
        return this.parents.get(a);
    }

    unite(a, b) {
        const rootA = this.find(a);
        const rootB = this.find(b);

        if (rootA === rootB) {
            return;
        }

        const codeA = rootA.charCodeAt(0);
        const codeB = rootB.charCodeAt(0);

        if (codeA > codeB) {
            this.parents.set(rootA, rootB);
        } else {
            this.parents.set(rootB, rootA);
        }
    }
}

0개의 댓글