Exemplo n.º 1
0
        public void UnionTest2()
        {
            var dsu = new DSU <int>();

            dsu.MakeSet(1);
            dsu.MakeSet(2);
            dsu.MakeSet(3);
            dsu.MakeSet(4);
            dsu.MakeSet(5);

            Assert.AreEqual(4, dsu.Find(4));


            dsu.Unite(1, 4, isRandom: false);
            dsu.Unite(3, 5, isRandom: false);

            Assert.AreEqual(1, dsu.Find(4));
            Assert.AreEqual(1, dsu.Find(1));
            Assert.AreEqual(2, dsu.Find(2));
            Assert.AreEqual(3, dsu.Find(5));
            Assert.AreEqual(3, dsu.Find(3));

            dsu.Unite(5, 2, isRandom: false);

            Assert.AreEqual(3, dsu.Find(5));
            Assert.AreEqual(3, dsu.Find(3));
            Assert.AreEqual(3, dsu.Find(2));
        }
Exemplo n.º 2
0
        public void UnionTest()
        {
            var dsu = new DSU <int>();

            dsu.MakeSet(1);
            dsu.MakeSet(2);

            dsu.Unite(1, 2, isRandom: false);

            Assert.That(dsu.Find(1), Is.EqualTo(dsu.Find(2)));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Nov. 19, 2020
        /// Union find algorithm
        /// study code
        /// https://leetcode.com/problems/sentence-similarity-ii/solution/
        /// Time complexity:
        /// Time Complexity: O(N log P + P), where N is the maximum length of words1 and words2,
        /// and P is the length of pairs. If we used union-by-rank, this complexity improves to
        /// O(N * a(P) + P), close to O(N + P), where α is the Inverse-Ackermann function.
        /// </summary>
        /// <param name="words1"></param>
        /// <param name="words2"></param>
        /// <param name="pairs"></param>
        /// <returns></returns>
        public bool AreSentencesSimilarTwo(string[] words1, string[] words2, IList <IList <string> > pairs)
        {
            var length1 = words1.Length;
            var length2 = words2.Length;
            var pLength = pairs.Count;

            if (length1 != length2)
            {
                return(false);
            }

            // index -> indexMap better name?
            var indexMap = new Dictionary <string, int>();

            int count = 0;

            var dsu = new DSU(2 * pLength);

            foreach (var pair in pairs)
            {
                // go through two words in one pair
                foreach (var p in pair)
                {
                    if (!indexMap.ContainsKey(p))
                    {
                        indexMap.Add(p, count++);
                    }
                }

                dsu.Union(indexMap[pair[0]], indexMap[pair[1]]);
            }

            for (int i = 0; i < length1; ++i)
            {
                var w1 = words1[i];
                var w2 = words2[i];

                if (w1.CompareTo(w2) == 0)
                {
                    continue;
                }

                if (!indexMap.ContainsKey(w1) ||
                    !indexMap.ContainsKey(w2) ||
                    dsu.Find(indexMap[w1]) != dsu.Find(indexMap[w2]))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 4
0
    public int RemoveStones(int[][] stones)
    {
        var dsu = new DSU(20000);

        foreach (var stone in stones)
        {
            dsu.Union(stone[0], stone[1] + 10000);
        }
        var seen = new HashSet <int>();

        foreach (var stone in stones)
        {
            seen.Add(dsu.Find(stone[0]));
        }
        return(stones.Length - seen.Count);
    }
Exemplo n.º 5
0
        public IList <IList <string> > AccountsMerge(IList <IList <string> > accounts)
        {
            EmailToId   = new Dictionary <string, int>();
            EmailToName = new Dictionary <string, string>();

            foreach (var account in accounts)
            {
                if (account.Count < 2)
                {
                    continue;
                }

                var name = account[0];
                for (var i = 1; i < account.Count; i++)
                {
                    if (!EmailToId.ContainsKey(account[i]))
                    {
                        var id = EmailToId.Count;
                        EmailToId[account[i]]   = id;
                        EmailToName[account[i]] = name;
                    }
                }
            }

            var totalAccounts = EmailToId.Count;

            DSU = new DSU(totalAccounts);

            foreach (var account in accounts)
            {
                // var name = account[0];
                for (var i = 1; i < account.Count - 1; i++)
                {
                    var id1 = EmailToId[account[i]];
                    var id2 = EmailToId[account[i + 1]];

                    if (id1 != id2)
                    {
                        DSU.Union(id1, id2);
                    }
                }
            }

            var result = new Dictionary <int, List <string> >();

            foreach (var email in EmailToName.Keys)
            {
                int index = DSU.Find(EmailToId[email]);
                if (result.TryGetValue(index, out var list))
                {
                    list.Add(email);
                }
                else
                {
                    result[index] = new List <string> {
                        email
                    };
                }
            }
            foreach (var emails in result.Values)
            {
                emails.Sort((x, y) =>
                {
                    var i = 0;
                    while (i < x.Length && i < y.Length)
                    {
                        if (x[i] != y[i])
                        {
                            return(x[i].CompareTo(y[i]));
                        }
                        i++;
                    }
                    return(x.Length.CompareTo(y.Length));
                });
                emails.Insert(0, EmailToName[emails[0]]);
            }
            return(result.Values.ToList <IList <string> >());
        }