Paul
Paul

Reputation: 353

The Value of Friendship : Disjoint set union

I am doing this challenge on HackerRank and I tried to use a mapping between students and sets to represent which group of friends the students belonged to :

The list of friends is instantiated with each student having himself as a friend and for performance reasons we keep the sets which the students belongs to :

map = [[1],[2],...[n]]

list = [1, 2,..., n]

So that the we know the student k where 0<=k<n is part of the set represented in list[k-1], 
and we know the set of friends the student is part of by retrieving map[list[k-1]]

Then, for each direct friendship added, I append the smallest set to the biggest set of friends, I update the set number of the students of the smallest set to match the biggest set, and adds to the sum of friends the value 2 * u * v, because the friendship is birectional (hence the 2*) and for each element of a set of size u, the element will make v new friends.

This code works for the test input but not for the rest of the tests and I cannot find why

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

class Result {

    /*
     * Complete the 'valueOfFriendship' function below.
     *
     * The function is expected to return an INTEGER.
     * The function accepts following parameters:
     *  1. INTEGER n
     *  2. 2D_INTEGER_ARRAY friendships
     */

    public static long valueOfFriendsship(int n, List<List<Integer>> friendships) {
        List<List<Integer>> sets = IntStream.range(1, n + 1).boxed().map((val)->new ArrayList<>(List.of(val))).collect(Collectors.toList());

         List<Integer> students = IntStream.range(1, n + 1).boxed().collect(Collectors.toList());
         long sum = 0;
         long total = 0;
         for (List<Integer> friendship : friendships) {
             int firstGroupIndex = students.get(friendship.get(0) - 1);
             int secondGroupIndex = students.get(friendship.get(1) - 1);
             if (firstGroupIndex != secondGroupIndex) {
                 List<Integer> firstGroup = sets.get(firstGroupIndex - 1);
                 List<Integer> secondGroup = sets.get(secondGroupIndex - 1);
                 sum += 2L * firstGroup.size() * secondGroup.size();
                 if (firstGroup.size() > secondGroup.size()) {
                     firstGroup.addAll(secondGroup);
                     secondGroup.forEach(val -> students.set(val - 1, firstGroupIndex));
                 } else {
                     secondGroup.addAll(firstGroup);
                     firstGroup.forEach(val -> students.set(val - 1, secondGroupIndex));
                 }
             }
             total += sum;
         }

        return total;
    }

}

Upvotes: 0

Views: 171

Answers (0)

Related Questions