1311. Get Watched Videos by Your Friends
There are n people, each person has a unique id between 0 and n-1. Given the arrays watchedVideos and friends, where watchedVideosi and friendsi contain the list of watched videos and the list of friends respectively for the person with id = i.
Level 1 of videos are all watched videos by your friends, level 2 of videos are all watched videos by the friends of your friends and so on. In general, the level k of videos are all watched videos by people with the shortest path exactly equal to k with you. Given your id and the level of videos, return the list of videos ordered by their frequencies (increasing). For videos with the same frequency order them alphabetically from least to greatest.
Example 1:

Input: watchedVideos = \["A","B","C","B","C","D"], friends = \[1,2,0,3,0,3,1,2], id = 0, level = 1
Output: "B","C"
Explanation:
You have id = 0 (green color in the figure) and your friends are (yellow color in the figure):
Person with id = 1 -> watchedVideos = "C"
Person with id = 2 -> watchedVideos = "B","C"
The frequencies of watchedVideos by your friends are:
B -> 1
C -> 2
Example 2:

Input: watchedVideos = \["A","B","C","B","C","D"], friends = \[1,2,0,3,0,3,1,2], id = 0, level = 2
Output: "D"
Explanation:
You have id = 0 (green color in the figure) and the only friend of your friends is the person with id = 3 (yellow color in the figure).
Constraints:
- n == watchedVideos.length == friends.length
- 2 <= n <= 100
- 1 <= watchedVideosi.length <= 100
- 1 <= watchedVideosij.length <= 8
- 0 <= friendsi.length < n
- 0 <= friendsij < n
- 0 <= id < n
- 1 <= level < n
- if friendsi contains j, then friendsj contains i
From: LeetCode
Link: 1311. Get Watched Videos by Your Friends
Solution:
Ideas:
Use BFS to find all people whose shortest distance from id is exactly level. Count their watched videos, then sort them by:
- Increasing frequency.
- Alphabetical order when frequencies are equal.
Code:
c
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct {
char* name;
int frequency;
} VideoInfo;
static int compareVideos(const void* a, const void* b) {
const VideoInfo* videoA = (const VideoInfo*)a;
const VideoInfo* videoB = (const VideoInfo*)b;
if (videoA->frequency != videoB->frequency) {
return videoA->frequency - videoB->frequency;
}
return strcmp(videoA->name, videoB->name);
}
static char* copyString(const char* source) {
int length = strlen(source);
char* copy = malloc((length + 1) * sizeof(char));
if (copy != NULL) {
strcpy(copy, source);
}
return copy;
}
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
char** watchedVideosByFriends(
char*** watchedVideos,
int watchedVideosSize,
int* watchedVideosColSize,
int** friends,
int friendsSize,
int* friendsColSize,
int id,
int level,
int* returnSize
) {
bool* visited = calloc(friendsSize, sizeof(bool));
int* queue = malloc(friendsSize * sizeof(int));
int front = 0;
int rear = 0;
queue[rear++] = id;
visited[id] = true;
/* BFS until the requested friendship level */
for (int currentLevel = 0; currentLevel < level; currentLevel++) {
int levelSize = rear - front;
for (int i = 0; i < levelSize; i++) {
int person = queue[front++];
for (int j = 0; j < friendsColSize[person]; j++) {
int nextFriend = friends[person][j];
if (!visited[nextFriend]) {
visited[nextFriend] = true;
queue[rear++] = nextFriend;
}
}
}
}
int maximumVideos = 0;
for (int i = front; i < rear; i++) {
maximumVideos += watchedVideosColSize[queue[i]];
}
VideoInfo* videos = malloc(maximumVideos * sizeof(VideoInfo));
int videoCount = 0;
/* Count videos watched by people at exactly the requested level */
for (int i = front; i < rear; i++) {
int person = queue[i];
for (int j = 0; j < watchedVideosColSize[person]; j++) {
char* videoName = watchedVideos[person][j];
int index = -1;
for (int k = 0; k < videoCount; k++) {
if (strcmp(videos[k].name, videoName) == 0) {
index = k;
break;
}
}
if (index == -1) {
videos[videoCount].name = videoName;
videos[videoCount].frequency = 1;
videoCount++;
} else {
videos[index].frequency++;
}
}
}
qsort(videos, videoCount, sizeof(VideoInfo), compareVideos);
char** answer = malloc(videoCount * sizeof(char*));
for (int i = 0; i < videoCount; i++) {
answer[i] = copyString(videos[i].name);
}
*returnSize = videoCount;
free(visited);
free(queue);
free(videos);
return answer;
}