leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit dac21b6c1b10e6792b00aa6aff0fbe508dc8e5b0
parent 2b8a977be2fc02f7a5050d3301d9b79015c98a0b
Author: Jack Sangdahl <jack@pngu.org>
Date:   Thu, 18 Dec 2025 20:42:04 -0700

2092. find all people with secret

Diffstat:
Mfind_all_people_secret.c | 147+++++++++++++++++++++++++++++--------------------------------------------------
Mfind_all_people_secret.py | 76+++++++++++++++++++++++++---------------------------------------------------
2 files changed, 78 insertions(+), 145 deletions(-)

diff --git a/find_all_people_secret.c b/find_all_people_secret.c @@ -13,117 +13,76 @@ * 'time_i' then they will share the secret with person 'y_i' and vice versa */ -int cmp(const void **a, const void **b) { - if ((*(int **)a)[2] == (*(int **)b)[2]) - return (*(int **)a)[0] - (*(int **)b)[0]; - return (*(int **)a)[2] - (*(int **)b)[2]; +int find(int *groups, int idx) { + while (idx != groups[idx]) + idx = groups[idx]; + return idx; } -void check(int *list, int a, int b, int i, int *returnSize, int *ans, int *time, - int *timecount) { - if (list[a] - list[b] == 1) { - list[b]++; - ans[*returnSize] = b; - *returnSize += 1; - } else if (list[b] - list[a] == 1) { - list[a]++; - ans[*returnSize] = a; - *returnSize += 1; - } else if (list[b] == 0 && list[a] == 0) { - time[*timecount] = i; - *timecount += 1; - } -} - -void sametime(int **meetings, int *ans, int *returnSize, int *time, - int timecount, int *list) { - int count = 1, newtimecount; - while (count) { - int copy = *returnSize; - newtimecount = 0; - for (int i = 0; i < timecount; i++) { - check(list, meetings[time[i]][0], meetings[time[i]][1], time[i], - returnSize, ans, time, &newtimecount); - } - count = *returnSize - copy; - if (count == 0) { - break; - } - copy = *returnSize; - timecount = newtimecount; - newtimecount = 0; - for (int i = timecount - 1; i >= 0; i--) { - check(list, meetings[time[i]][0], meetings[time[i]][1], time[i], - returnSize, ans, time, &newtimecount); - } - count = *returnSize - copy; - timecount = newtimecount; - } +int cmp(const void *a, const void *b) { + const int *aa = *(const int **)a; + const int *bb = *(const int **)b; + return aa[2] - bb[2]; } int *findAllPeople(int n, int **meetings, int meetingsSize, int *meetingsColSize, int firstPerson, int *returnSize) { - int *list = calloc(n, sizeof(int)); - int *ans = malloc(sizeof(int) * n); - int *time = malloc(sizeof(int) * n); - int timecount = 0; - *returnSize = 2; - for (int i = 0; i < meetingsSize; i++) { - if (meetings[i][0] > meetings[i][1]) { - int a = meetings[i][1]; - meetings[i][1] = meetings[i][0]; - meetings[i][0] = a; - } - } - qsort(meetings, meetingsSize, sizeof(int *), cmp); - list[0]++; - list[firstPerson]++; - ans[0] = 0; - ans[1] = firstPerson; - for (int i = 0; i < meetingsSize; i++) { - if (list[meetings[i][0]] - list[meetings[i][1]] == 1) { - list[meetings[i][1]]++; - ans[*returnSize] = meetings[i][1]; - *returnSize += 1; - } else if (list[meetings[i][1]] - list[meetings[i][0]] == 1) { - list[meetings[i][0]]++; - ans[*returnSize] = meetings[i][0]; - *returnSize += 1; - } else if (i + 1 < meetingsSize && meetings[i][2] == meetings[i + 1][2]) { - timecount = 0; - check(list, meetings[i][0], meetings[i][1], i, returnSize, ans, time, - &timecount); + int *groups = (int *)malloc(n * sizeof(int)); + int *ans = (int *)malloc(n * sizeof(int)); + for (int i = 0; i < n; i++) + groups[i] = i; + groups[firstPerson] = 0; + qsort(meetings, meetingsSize, sizeof(meetings[0]), cmp); + int *tmp = (int *)malloc(2 * n * sizeof(int)); + int ans_cnt = 0, i = 0; + while (i < meetingsSize) { + int curr_time = meetings[i][2], tmp_cnt = 0; + while (i < meetingsSize && meetings[i][2] == curr_time) { + int g1 = find(groups, meetings[i][0]), g2 = find(groups, meetings[i][1]); + groups[g1 > g2 ? g1 : g2] = g1 < g2 ? g1 : g2; + tmp[tmp_cnt++] = meetings[i][0]; + tmp[tmp_cnt++] = meetings[i][1]; i++; - while (i + 1 < meetingsSize && meetings[i][2] == meetings[i + 1][2]) { - check(list, meetings[i][0], meetings[i][1], i, returnSize, ans, time, - &timecount); - i++; - } - check(list, meetings[i][0], meetings[i][1], i, returnSize, ans, time, - &timecount); - sametime(meetings, ans, returnSize, time, timecount, list); } + for (int j = 0; j < tmp_cnt; j++) + if (find(groups, tmp[j])) + groups[tmp[j]] = tmp[j]; } - free(list); - free(time); + for (int j = 0; j < n; j++) + if (!find(groups, j)) + ans[ans_cnt++] = j; + free(tmp); + free(groups); + *returnSize = ans_cnt; return ans; } int main() { - int m1[3][3] = {{1, 2, 5}, {2, 3, 8}, {1, 5, 10}}, - m2[3][3] = {{3, 1, 3}, {1, 2, 2}, {0, 3, 3}}, - m3[3][3] = {{3, 4, 2}, {1, 2, 1}, {2, 3, 1}}; - int *mcs1, *mcs2, *mcs3, *rs1, *rs2, *rs3; - int *fap1 = findAllPeople(6, (int **)m1, 3, mcs1, 1, rs1); - int *fap2 = findAllPeople(4, (int **)m2, 3, mcs2, 1, rs2); - int *fap3 = findAllPeople(5, (int **)m3, 3, mcs3, 1, rs3); + int m1i[3][3] = {{1, 2, 5}, {2, 3, 8}, {1, 5, 10}}, rs1; + int m2i[3][3] = {{3, 1, 3}, {1, 2, 2}, {0, 3, 3}}, rs2; + int m3i[3][3] = {{3, 4, 2}, {1, 2, 1}, {2, 3, 1}}, rs3; + struct two_d_arr *m1 = + two_d_arr_init(ARRAY_SIZE(m1i), ARRAY_SIZE(m1i[0]), m1i); + struct two_d_arr *m2 = + two_d_arr_init(ARRAY_SIZE(m2i), ARRAY_SIZE(m2i[0]), m2i); + struct two_d_arr *m3 = + two_d_arr_init(ARRAY_SIZE(m3i), ARRAY_SIZE(m3i[0]), m3i); + int *fap1 = findAllPeople(6, m1->arr, m1->row_size, m1->col_size, 1, &rs1); + int *fap2 = findAllPeople(4, m2->arr, m2->row_size, m2->col_size, 3, &rs2); + int *fap3 = findAllPeople(5, m3->arr, m3->row_size, m3->col_size, 1, &rs3); for (int i = 0; i < 5; i++) - printf("%d ", fap1[i]); + printf("%d ", fap1[i]); // expect: 0 1 2 3 5 printf("\n"); for (int i = 0; i < 3; i++) - printf("%d ", fap2[i]); + printf("%d ", fap2[i]); // expect: 0 1 3 printf("\n"); for (int i = 0; i < 5; i++) - printf("%d ", fap3[i]); + printf("%d ", fap3[i]); // expect: 0 1 2 3 4 printf("\n"); + free(fap1); + free(fap2); + free(fap3); + two_d_arr_free(m1); + two_d_arr_free(m2); + two_d_arr_free(m3); } diff --git a/find_all_people_secret.py b/find_all_people_secret.py @@ -1,5 +1,4 @@ # 2092. Find All People With Secret -from collections import defaultdict """ given an integer 'n' indicating there are 'n' people numbered from 0 to 'n - @@ -15,6 +14,11 @@ that has the secret. more formall, for every meeting 'x_i', has secret at class Solution(object): + def find(self, groups, idx): + while idx != groups[idx]: + idx = groups[idx] + return idx + def findAllPeople(self, n, meetings, firstPerson): """ :type n: int @@ -22,56 +26,26 @@ class Solution(object): :type firstPerson: int :rtype: List[int] """ - - class UnionFind: - def __init__(self): - self.parents = {} - self.ranks = {} - - def insert(self, x): - if x not in self.parents: - self.parents[x] = x - self.ranks[x] = 0 - - def find_parent(self, x): - if self.parents[x] != x: - self.parents[x] = self.find_parent(self.parents[x]) - return self.parents[x] - - def union(self, x, y): - self.insert(x) - self.insert(y) - x, y = self.find_parent(x), self.find_parent(y) - if x == y: - return - if self.ranks[x] > self.ranks[y]: - self.parents[y] = x - else: - self.parents[x] = y - if self.ranks[x] == self.ranks[y]: - self.ranks[y] += 1 - - time2meets = defaultdict(list) - for x, y, t in meetings: - time2meets[t].append((x, y)) - time2meets = sorted(time2meets.items()) - - curr_know = set([0, firstPerson]) - - for time, meets in time2meets: - uf = UnionFind() - for x, y in meets: - uf.union(x, y) - - groups = defaultdict(set) - for idx in uf.parents: - groups[uf.find_parent(idx)].add(idx) - - for group in groups.values(): - if group & curr_know: - curr_know.update(group) - - return list(curr_know) + groups = [i for i in range(n)] + groups[firstPerson] = 0 + meetings.sort(key=lambda x: x[2]) + size, i = len(meetings), 0 + while i < size: + curr_time, tmp = meetings[i][2], [] + while i < size and meetings[i][2] == curr_time: + g1 = self.find(groups, meetings[i][0]) + g2 = self.find(groups, meetings[i][1]) + groups[max(g1, g2)] = min(g1, g2) + tmp.extend([meetings[i][0], meetings[i][1]]) + i += 1 + for j in tmp: + if self.find(groups, j) != 0: + groups[j] = j + ans = [] + for j in range(n): + if self.find(groups, j) == 0: + ans.append(j) + return ans if __name__ == "__main__":