Skip to content

Commit 2bf5fef

Browse files
authored
Create get-watched-videos-by-your-friends.md
1 parent 7f73d19 commit 2bf5fef

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
id: get-watched-videos-by-your-friends
3+
title: Get Watched Videos by Your Friends
4+
sidebar_label: Get Watched Videos by Your Friends
5+
tags: [Graph, BFS, C++, Python, Java]
6+
description: Find the list of videos watched by friends up to a certain level, ordered by their frequencies.
7+
---
8+
9+
## Problem Statement
10+
11+
### Problem Description
12+
13+
There are `n` people, each person has a unique id between `0` and `n-1`. Given the arrays `watchedVideos` and `friends`, where `watchedVideos[i]` and `friends[i]` contain the list of watched videos and the list of friends respectively for the person with id `i`.
14+
15+
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.
16+
17+
### Example
18+
19+
**Example 1:**
20+
21+
```
22+
Input: watchedVideos = [["A","B"],["C"],["B","C"],["D"]], friends = [[1,2],[0,3],[0,3],[1,2]], id = 0, level = 1
23+
Output: ["B","C"]
24+
```
25+
**Explanation:**
26+
You have id = 0 (green color in the figure) and your friends are (yellow color in the figure):
27+
Person with id = 1 -> watchedVideos = ["C"]
28+
Person with id = 2 -> watchedVideos = ["B","C"]
29+
The frequencies of watchedVideos by your friends are:
30+
B -> 1
31+
C -> 2
32+
33+
34+
### Constraints
35+
36+
- `n == watchedVideos.length == friends.length`
37+
- `2 <= n <= 100`
38+
- `1 <= watchedVideos[i].length <= 100`
39+
- `1 <= watchedVideos[i][j].length <= 8`
40+
- `0 <= friends[i].length < n`
41+
- `0 <= friends[i][j] < n`
42+
- `0 <= id < n`
43+
- `1 <= level < n`
44+
- If `friends[i]` contains `j`, then `friends[j]` contains `i`
45+
46+
## Solution
47+
48+
### Intuition
49+
50+
To solve this problem, we use a Breadth-First Search (BFS) approach to explore all friends up to the specified level. We start from the given `id` and use a queue to perform BFS. At each level, we gather the videos watched by the friends and keep track of the frequencies. We then sort the videos by frequency and alphabetically for those with the same frequency.
51+
52+
### Time Complexity and Space Complexity Analysis
53+
54+
- **Time Complexity**: The time complexity is $O(n \cdot m \cdot \log m)$, where `n` is the number of people and `m` is the maximum number of videos watched by any person. This is due to the BFS traversal and the sorting of the video frequencies.
55+
- **Space Complexity**: The space complexity is $O(n \cdot m)$ due to the space needed for the BFS queue and the frequency map.
56+
57+
### Code
58+
59+
#### Python
60+
```python
61+
from collections import deque, Counter
62+
63+
class Solution:
64+
def watchedVideosByFriends(self, watchedVideos: List[List[str]], friends: List[List[int]], id: int, level: int) -> List[str]:
65+
video_frequency = Counter()
66+
visited = [False] * len(friends)
67+
q = deque([id])
68+
visited[id] = True
69+
current_level = 0
70+
71+
while q:
72+
size = len(q)
73+
if current_level == level:
74+
break
75+
for _ in range(size):
76+
person = q.popleft()
77+
for friend in friends[person]:
78+
if not visited[friend]:
79+
visited[friend] = True
80+
q.append(friend)
81+
current_level += 1
82+
83+
while q:
84+
person = q.popleft()
85+
video_frequency.update(watchedVideos[person])
86+
87+
return sorted(video_frequency.keys(), key=lambda x: (video_frequency[x], x))
88+
```
89+
90+
#### C++
91+
92+
```cpp
93+
#include <vector>
94+
#include <string>
95+
#include <unordered_map>
96+
#include <queue>
97+
#include <algorithm>
98+
using namespace std;
99+
100+
class Solution {
101+
public:
102+
vector<string> watchedVideosByFriends(vector<vector<string>>& watchedVideos, vector<vector<int>>& friends, int id, int level) {
103+
vector<string> result;
104+
unordered_map<string, int> videoFrequency;
105+
vector<bool> visited(friends.size(), false);
106+
queue<int> q;
107+
q.push(id);
108+
visited[id] = true;
109+
int currentLevel = 0;
110+
111+
while (!q.empty()) {
112+
int size = q.size();
113+
if (currentLevel == level) break;
114+
115+
while (size--) {
116+
int person = q.front();
117+
q.pop();
118+
for (int friendId : friends[person]) {
119+
if (!visited[friendId]) {
120+
visited[friendId] = true;
121+
q.push(friendId);
122+
}
123+
}
124+
}
125+
currentLevel++;
126+
}
127+
128+
while (!q.empty()) {
129+
int person = q.front();
130+
q.pop();
131+
for (const string& video : watchedVideos[person]) {
132+
videoFrequency[video]++;
133+
}
134+
}
135+
136+
vector<pair<string, int>> videoList(videoFrequency.begin(), videoFrequency.end());
137+
sort(videoList.begin(), videoList.end(), [](const pair<string, int>& a, const pair<string, int>& b) {
138+
if (a.second == b.second) return a.first &lt; b.first;
139+
return a.second &lt; b.second;
140+
});
141+
142+
for (const auto& [video, freq] : videoList) {
143+
result.push_back(video);
144+
}
145+
146+
return result;
147+
}
148+
};
149+
```
150+
#### Java
151+
```java
152+
import java.util.*;
153+
154+
class Solution {
155+
public List<String> watchedVideosByFriends(List<List<String>> watchedVideos, List<List<Integer>> friends, int id, int level) {
156+
Map<String, Integer> videoFrequency = new HashMap<>();
157+
boolean[] visited = new boolean[friends.size()];
158+
Queue<Integer> queue = new LinkedList<>();
159+
queue.add(id);
160+
visited[id] = true;
161+
int currentLevel = 0;
162+
163+
while (!queue.isEmpty()) {
164+
int size = queue.size();
165+
if (currentLevel == level) break;
166+
167+
for (int i = 0; i &lt; size; i++) {
168+
int person = queue.poll();
169+
for (int friend : friends.get(person)) {
170+
if (!visited[friend]) {
171+
visited[friend] = true;
172+
queue.add(friend);
173+
}
174+
}
175+
}
176+
currentLevel++;
177+
}
178+
179+
while (!queue.isEmpty()) {
180+
int person = queue.poll();
181+
for (String video : watchedVideos.get(person)) {
182+
videoFrequency.put(video, videoFrequency.getOrDefault(video, 0) + 1);
183+
}
184+
}
185+
186+
List<Map.Entry<String, Integer>> videoList = new ArrayList<>(videoFrequency.entrySet());
187+
videoList.sort((a, b) -> {
188+
if (a.getValue().equals(b.getValue())) return a.getKey().compareTo(b.getKey());
189+
return Integer.compare(a.getValue(), b.getValue());
190+
});
191+
192+
List<String> result = new ArrayList<>();
193+
for (Map.Entry<String, Integer> entry : videoList) {
194+
result.add(entry.getKey());
195+
}
196+
197+
return result;
198+
}
199+
}
200+
```

0 commit comments

Comments
 (0)