Solution For The Earliest Moment When Everyone Become Friends
Problem:
There are n people in a social group labeled from 0 to n-1. You are given a log file logs where logs[i] = [timestamp_i, from_i, to_i] indicates that from_i and to_i became friends at the time timestamp_i.
Back to present time, all friendships are formed. You need to find the earliest time when everyone in the group became friends. If there is no such a time, return -1.
Example 1:
Input: n = 2, logs = [[0,1,2],[0,2,3],[1,3,4],[1,4,5],[2,3,4],[3,4,5]],
Output: 3
Explanation: The earliest time when everyone became friends is 3. At time 3, group 1 [0,1,2,3,4,5] became friends.
Solution:
To solve this problem, we can use Union Find data structure. We need to maintain a parent array where parent[i] will store the parent node of i. Initially, all nodes will be the parent of themselves. We also need to maintain a rank array where rank[i] will store the rank of i.
The rank is used to maintain the height of the tree. We try to merge smaller trees with bigger trees to get a more balanced tree and thus more efficient Union Find operations.
The day when everyone becomes friends is when the number of connected components reduces to one. We can keep track of the number of connected components using a variable count.
Initially, when all n nodes are not connected to any other node, count=n. For each log, we check whether the from and to nodes are already connected or not using find function. If the nodes are not connected, we merge them using union function and reduce count by one.
We keep doing this until count becomes one or we have checked all logs. If count never becomes one, that means all nodes are not connected with each other, so we return -1. Otherwise, we return the timestamp at which all nodes are connected.
Implementation:
Here is the Python code for the implementation:
“`
class UnionFind:
def init(self, n: int):
self.parent = list(range(n))
self.rank = [0]*n
self.count = n
def find(self, i: int) -> int:
while i != self.parent[i]:
self.parent[i] = self.parent[self.parent[i]]
i = self.parent[i]
return i
def union(self, i: int, j: int) -> bool:
parent_i, parent_j = self.find(i), self.find(j)
if parent_i == parent_j:
return False
if self.rank[parent_i] < self.rank[parent_j]:
parent_i, parent_j = parent_j, parent_i
self.parent[parent_j] = parent_i
if self.rank[parent_i] == self.rank[parent_j]:
self.rank[parent_i] += 1
self.count -= 1
return True
class Solution:
def earliestAcq(self, logs: List[List[int]], n: int) -> int:
logs.sort()
uf = UnionFind(n)
for log in logs:
uf.union(log[1], log[2])
if uf.count == 1:
return log[0]
return -1
“`
Time Complexity: The time complexity of this algorithm is O(nlogn) where n is the number of logs. Sorting of logs takes O(nlogn) time. The for loop runs n times and inside the loop, we do find and union operations which take O(alpha(n)) time (almost constant time) where alpha(n) is the inverse Ackermann function which is a very slowly growing function.
Space Complexity: The space complexity of this algorithm is O(n) where n is the number of nodes. We need to maintain a parent and rank array for each node.
Step by Step Implementation For The Earliest Moment When Everyone Become Friends
This is a Java solution for the leetcode problem "the-earliest-moment-when-everyone-become-friends". /* In a social group, there are N people, with unique numerical ID from 0 to N-1. We have a list of logs, where each log is a pair of ID's for two people that became friends at some time. Each log is a string with the format "[ID1] [ID2] [timestamp]", where [ID1] and [ID2] are two numerical IDs of two people, and [timestamp] is the time when they became friends. Friendships are symmetric: if A is friends with B, then B is friends with A. Let's say that person A is acquainted with person B if A is friends with B, or A is a friend of someone acquainted with B. Return the earliest time for which every person became acquainted with every other person. Return -1 if there is no such earliest time. Example 1: Input: logs = ["[0,1,1]","[1,2,2]","[2,3,3]","[3,4,4]","[4,5,5]","[5,6,6]","[6,7,7]","[7,0,8]"], N = 8 Output: 8 Explanation: The first event occurs at timestamp = 1 and after 0 seconds friends of each person become friends. The second event occurs at timestamp = 2 and after 0 seconds friends of each person become friends. The third event occurs at timestamp = 3 and after 0 seconds friends of each person become friends. The fourth event occurs at timestamp = 4 and after 0 seconds friends of each person become friends. The fifth event occurs at timestamp = 5 and after 0 seconds friends of each person become friends. The sixth event occurs at timestamp = 6 and after 0 seconds friends of each person become friends. The seventh event occurs at timestamp = 7 and after 0 seconds friends of each person become friends. The eighth event occurs at timestamp = 8 and after 0 seconds friends of each person become friends. So, the answer is 8. Example 2: Input: logs = ["[0,1,1]","[1,2,2]","[2,3,3]","[3,4,4]","[4,5,5]","[5,6,6]","[6,7,7]","[7,0,8]","[8,1,9]","[9,0,10]","[10,1,11]","[11,2,12]","[12,2,13]","[13,3,14]","[14,4,15]","[15,4,16]","[16,5,17]","[17,6,18]","[18,7,19]","[19,0,20]","[20,8,21]","[21,9,22]","[22,10,23]","[23,11,24]","[24,12,25]","[25,12,26]","[26,13,27]","[27,14,28]","[28,15,29]","[29,16,30]","[30,17,31]","[31,18,32]","[32,19,33]","[33,20,34]","[34,21,35]","[35,22,36]","[36,23,37]","[37,24,38]","[38,25,39]","[39,26,40]","[40,27,41]","[41,28,42]","[42,29,43]","[43,30,44]","[44,31,45]","[45,32,46]","[46,33,47]","[47,34,48]","[48,35,49]","[49,36,50]","[50,37,51]","[51,38,52]","[52,39,53]","[53,40,54]","[54,41,55]","[55,42,56]","[56,43,57]","[57,44,58]","[58,45,59]","[59,46,60]","[60,47,61]","[61,48,62]","[62,49,63]","[63,50,64]","[64,51,65]","[65,52,66]","[66,53,67]","[67,54,68]","[68,55,69]","[69,56,70]","[70,57,71]","[71,58,72]","[72,59,73]","[73,60,74]","[74,61,75]","[75,62,76]","[76,63,77]","[77,64,78]","[78,65,79]","[79,66,80]","[80,67,81]","[81,68,82]","[82,69,83]","[83,70,84]","[84,71,85]","[85,72,86]","[86,73,87]","[87,74,88]","[88,75,89]","[89,76,90]","[90,77,91]","[91,78,92]","[92,79,93]","[93,80,94]","[94,81,95]","[95,82,96]","[96,83,97]","[97,84,98]","[98,85,99]","[99,86,100]","[100,87,101]","[101,88,102]","[102,89,103]","[103,90,104]","[104,91,105]","[105,92,106]","[106,93,107]","[107,94,108]","[108,95,109]","[109,96,110]","[110,97,111]","[111,98,112]","[112,99,113]","[113,100,114]","[114,101,115]","[115,102,116]","[116,103,117]","[117,104,118]","[118,105,119]","[119,106,120]","[120,107,121]","[121,108,122]","[122,109,123]","[123,110,124]","[124,111,125]","[125,112,126]","[126,113,127]","[127,114,128]","[128,115,129]","[129,116,130]","[130,117,131]","[131,118,132]","[132,119,133]","[133,120,134]","[134,121,135]","[135,122,136]","[136,123,137]","[137,124,138]","[138,125,139]","[139,126,140]","[140,127,141]","[141,128,142]","[142,129,143]","[143,130,144]","[144,131,145]","[145,132,146]","[146,133,147]","[147,134,148]","[148,135,149]","[149,136,150]","[150,137,151]","[151,138,152]","[152,139,153]","[153,140,154]","[154,141,155]","[155,142,156]","[156,143,157]","[157,144,158]","[158,145,159]","[159,146,160]","[160,147,161]","[161,148,162]","[162,149,163]","[163,150,164]","[164,151,165]","[165,152,166]","[166,153,167]","[167,154,168]","[168,155,169]","[169,156,170]","[170,157,171]","[171,158,172]","[172,159,173]","[173,160,174]","[174,161,175]","[175,162,176]","[176,163,177]","[177,164,178]","[178,165,179]","[179,166,180]","[180,167,181]","[181,168,182]","[182,169,183]","[183,170,184]","[184,171,185]","[185,172,186]","[186,173,187]","[187,174,188]","[188,175,189]","[189,176,190]","[190,177,191]","[191,178,192]","[192,179,193]","[193,180,194]","[194,181,195]","[195,182,196]","[196,183,197]","[197,184,198]","[198,185,199]","[199,186,200]","[200,187,201]","[201,188,202]","[202,189,203]","[203,190,204]","[204,191,205]","[205,192,206]","[206,193,207]","[207,194,208]","[208,195,209]","[209,196,210]","[210,197,211]","[211,198,212]","[212,199,213]","[213,200,214]","[214,201,215]","[215,202,216]","[216,203,217]","[217,204,218]","[218,205,219]","[219,206,220]","[220,207,221]","[221,208,222]","[222,209,223]","[223,210,224]","[224,211,225]","[225,212,226]","[226,213,227]","[227,214,228]","[228,215,229]","[229,216,230]","[230,217,231]","[231,218,232]","[232,219,233]","[233,220,234]","[234,221,235]","[235,222,236]","[236,223,237]","[237,224,238]","[238,225,239]","[239,226,240]","[240,227,241]","[241,228,242]","[242,229,243]","[243,230,244]","[244,231,245]","[245,232,246]","[246,233,247]","[247,234,248]","[248,235,249]","[249,236,250]","[250,237,251]","[251,238,252]","[252,239,253]","[253,240,254]","[254,241,255]","[255,242,256]","[256,243,257]","[257,244,258]","[258,245,259]","[259,246,260]","[260,247,261]","[261,248,262]","[262,249,263]","[263,250,264]","[264,251,265]","[265,252,266]","[266,253,267]","[267,254,268]","[268,255,269]","[269,256,270]","[270,257,271]","[271,258,272]","[272,259,273]","[273,260,274]","[274,261,275]","[275,262,276]","[276,263,277]","[277,264,278]","[278,265,279]","[279,266,280]","[280,267,281]","[281,268,282]","[282,269,283]","[283,270,284]","[284,271,285]","[285,272,286]","[286,273,287]","[287,274,288]","[288,275,289]","[289,276,290]","[290,277,291]","[291,278,292]","[292,279,293]","[293,280,294]","[294,281,295]","[295,282,296]","[296,283,297]","[297,284,298]","[298,285,299]","[299,286,300]","[300,287,301]","[301,288,302]","[302,289,303]","[303,290,304]","[304,291,305]","[305,292,306]","[306,293,307]","[307,294,308]","[308,295,309]","[309,296,310]","[310,297,311]","[311,298,312]","[312,299,313]","[313,300,314]","[314,301,315]","[315,302,316]","[316,303,317]","[317,304,318]","[318,305,319]","[319,306,320]","[320,307,321]","[321,308,322]","[322,309,323]","[323,310,324]","[324,311,325]","[
This is a Python solution for the leetcode problem "the-earliest-moment-when-everyone-become-friends". The output should only consist of exact code with comments and nothing else. def earliestMoment(self, n, logs): # create a list of all the people people = [i for i in range(n)] # create a dictionary to store the times when each person becomes friends with another person # the key is the person, the value is a list of times when that person becomes friends with someone times = {} # go through all the logs for log in logs: # split the log into two parts, the first part is the time and the second part is the list of people time, p1, p2 = log.split() # convert the time to an int time = int(time) # convert the people to ints p1 = int(p1) p2 = int(p2) # if the first person is not in the dictionary, add them if p1 not in times: times[p1] = [] # if the second person is not in the dictionary, add them if p2 not in times: times[p2] = [] # add the time to the list of times for each person times[p1].append(time) times[p2].append(time) # sort the lists of times for each person for person in times: times[person].sort() # go through all the people for person in people: # get the list of times for this person p_times = times[person] # go through all the other people for other in people: # if this is the same person, skip them if person == other: continue # get the list of times for the other person o_times = times[other] # find the earliest time that both people are friends i = 0 j = 0 while i < len(p_times) and j < len(o_times): # if the time for the first person is before the time for the second person, increment the first person's index if p_times[i] < o_times[j]: i += 1 # if the time for the second person is before the time for the first person, increment the second person's index elif p_times[i] > o_times[j]: j += 1 # if the times are equal, this is the earliest time that both people are friends, so break out of the loop else: break # if we reached the end of either list without finding a matching time, then there is no earliest time that both people are friends, so return -1 if i == len(p_times) or j == len(o_times): return -1 # otherwise, return the earliest time that both people are friends else: return p_times[i]
var earliestMoment = function(times, N) { // Create a graph using an adjacency list let graph = new Map(); for (let i = 0; i < N; i++) { graph.set(i, []); } for (let time of times) { let u = time[0], v = time[1], w = time[2]; graph.get(u).push([v, w]); graph.get(v).push([u, w]); } // Create a priority queue and add all vertices with a distance of 0 let pq = new PriorityQueue({comparator: (a, b) => a[1] - b[1]}); for (let i = 0; i < N; i++) { pq.queue([i, 0]); } // Create a set to track visited vertices let visited = new Set(); // While the priority queue is not empty while (!pq.isEmpty()) { // Dequeue a vertex let [u, d] = pq.dequeue(); // If the vertex has not been visited if (!visited.has(u)) { // Mark it as visited visited.add(u); // For each neighbor of the dequeued vertex for (let [v, w] of graph.get(u)) { // If the neighbor has not been visited if (!visited.has(v)) { // Enqueue the neighbor with a distance of d + w pq.queue([v, d + w]); } } // If all vertices have been visited if (visited.size === N) { // Return the distance of the dequeued vertex return d; } } } // If we get here, then there is no path from any vertex to all other vertices return -1; };
One possible solution to this problem is to use a Union-Find data structure. We can initialize each person to be in their own disjoint set. Then, as we process each friendship, we can union the two people involved in the friendship. Once we have processed all friendships, we can iterate through all people and find the earliest moment when everyone is in the same disjoint set. Here is some pseudocode for this solution: initialize each person to be in their own disjoint set for each friendship: union the two people involved in the friendship for each person: find the earliest moment when everyone is in the same disjoint set This solution has a time complexity of O(N + M), where N is the number of people and M is the number of friendships.
using System; public class Solution { // Find the earliest time when every person becomes friends public int FindEarliestTime(int[][] times) { // Create a list of people and initialize all of them to not be friends with anyone Listpeople = new List (); for (int i = 0; i < times.Length; i++) { people.Add(i); } // Sort the list of times by the earliest time Array.Sort(times, (a, b) => a[2] - b[2]); // Loop through the list of times for (int i = 0; i < times.Length; i++) { // Get the two people for this time int person1 = times[i][0]; int person2 = times[i][1]; // If they are not friends, make them friends if (!people.Contains(person1) || !people.Contains(person2)) { people.Add(person1); people.Add(person2); } // If everyone is friends, return the time if (people.Count == times.Length) { return times[i][2]; } } // If everyone is not friends by the end, return -1 return -1; } }