2456. Most Popular Video Creator
Problem Description
You are given three arrays of the same length n
:
creators
: string array containing creator namesids
: string array containing video IDsviews
: integer array containing view counts
Each index i
represents a video where:
creators[i]
is the creator who made the videoids[i]
is the video's IDviews[i]
is the number of views for that video
The popularity of a creator is defined as the total sum of views across all their videos.
Your task is to find:
- The creator(s) with the highest popularity (if multiple creators tie for highest, find all of them)
- For each of these top creators, find the ID of their most viewed video
- If a creator has multiple videos with the same highest view count, choose the ID that is lexicographically smallest
Important notes:
- Different videos can have the same ID (IDs don't uniquely identify videos)
- Videos with the same ID are still considered distinct videos with their own view counts
Return a 2D array where each element is [creator_name, most_popular_video_id]
representing a creator with the highest popularity and the ID of their most popular video. The order of the results doesn't matter.
Example scenario: If creator "Alice" has videos with IDs ["video1", "video2"] and views [100, 200], Alice's popularity is 300 and her most popular video ID is "video2".
Intuition
To solve this problem, we need to track two key pieces of information for each creator:
- Their total popularity (sum of all their video views)
- Their most popular video's ID
The natural approach is to process all videos once and aggregate the data by creator. As we iterate through the videos, we can simultaneously:
- Add up the views for each creator to calculate their total popularity
- Keep track of which video is currently the most popular for each creator
For tracking the most popular video per creator, we need to handle the tie-breaking rule: when multiple videos have the same view count, we choose the lexicographically smallest ID. This means whenever we encounter a new video for a creator, we update their most popular video if:
- The new video has more views than the current most popular, OR
- The new video has the same views but a lexicographically smaller ID
Using hash tables (dictionaries) is ideal here because:
- We need to group data by creator name (which can be any string)
- We need quick lookups and updates as we process each video
- The number of unique creators is unknown beforehand
After processing all videos, finding the answer becomes straightforward:
- Find the maximum total popularity across all creators
- Return all creators who have this maximum popularity along with their most popular video's ID
The key insight is that we can do all the necessary bookkeeping in a single pass through the data, making this solution efficient with O(n)
time complexity where n
is the number of videos.
Learn more about Sorting and Heap (Priority Queue) patterns.
Solution Approach
We use two hash tables to solve this problem:
cnt
: Maps each creator to their total view count (popularity)d
: Maps each creator to the index of their most popular video
Step 1: Process all videos
We iterate through all three arrays simultaneously using zip(creators, ids, views)
along with enumerate
to keep track of indices:
for k, (c, i, v) in enumerate(zip(creators, ids, views)):
For each video:
- Add the views to the creator's total:
cnt[c] += v
- Update the creator's most popular video index if needed
Step 2: Track the most popular video for each creator
For updating the most popular video, we check three conditions:
if c not in d or views[d[c]] < v or (views[d[c]] == v and ids[d[c]] > i): d[c] = k
This updates the index when:
c not in d
: First video for this creatorviews[d[c]] < v
: Current video has more views than the stored oneviews[d[c]] == v and ids[d[c]] > i
: Same views but current video has lexicographically smaller ID
Step 3: Find the maximum popularity
After processing all videos, find the highest total view count:
mx = max(cnt.values())
Step 4: Build the result
Create the answer by finding all creators with maximum popularity:
return [[c, ids[d[c]]] for c, x in cnt.items() if x == mx]
For each creator c
with popularity x
equal to mx
, we include [creator_name, most_popular_video_id]
where the video ID is retrieved using ids[d[c]]
(the ID at the stored index).
Time Complexity: O(n)
where n
is the number of videos, as we iterate through the arrays once and perform constant-time operations for each video.
Space Complexity: O(m)
where m
is the number of unique creators, for storing the hash tables.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example to illustrate the solution approach.
Input:
creators = ["Alice", "Bob", "Alice", "Chris", "Bob"]
ids = ["video1", "video2", "video3", "video4", "video2"]
views = [100, 200, 150, 50, 300]
Step 1: Initialize our hash tables
cnt = {}
(for tracking total views per creator)d = {}
(for tracking index of most popular video per creator)
Step 2: Process each video
Video 0: creator="Alice", id="video1", views=100
cnt["Alice"] = 100
(first video for Alice)d["Alice"] = 0
(store index 0 as Alice's most popular video)
Video 1: creator="Bob", id="video2", views=200
cnt["Bob"] = 200
(first video for Bob)d["Bob"] = 1
(store index 1 as Bob's most popular video)
Video 2: creator="Alice", id="video3", views=150
cnt["Alice"] = 100 + 150 = 250
(add to Alice's total)- Check if we need to update
d["Alice"]
:- Current most popular:
views[0] = 100
- New video:
views[2] = 150
- Since 150 > 100, update
d["Alice"] = 2
- Current most popular:
Video 3: creator="Chris", id="video4", views=50
cnt["Chris"] = 50
(first video for Chris)d["Chris"] = 3
(store index 3 as Chris's most popular video)
Video 4: creator="Bob", id="video2", views=300
cnt["Bob"] = 200 + 300 = 500
(add to Bob's total)- Check if we need to update
d["Bob"]
:- Current most popular:
views[1] = 200
- New video:
views[4] = 300
- Since 300 > 200, update
d["Bob"] = 4
- Current most popular:
Step 3: Find maximum popularity
cnt = {"Alice": 250, "Bob": 500, "Chris": 50}
mx = max(250, 500, 50) = 500
Step 4: Build result
- Only Bob has popularity = 500
- Bob's most popular video index is
d["Bob"] = 4
- The ID at index 4 is
ids[4] = "video2"
- Result:
[["Bob", "video2"]]
Handling tie-breaking scenario: If Alice had two videos both with 150 views but IDs "video3" and "video1", we would choose "video1" because it's lexicographically smaller ("video1" < "video3").
Solution Implementation
1class Solution:
2 def mostPopularCreator(
3 self, creators: List[str], ids: List[str], views: List[int]
4 ) -> List[List[str]]:
5 # Dictionary to store total views for each creator
6 creator_total_views = defaultdict(int)
7
8 # Dictionary to store the index of the best video for each creator
9 # Best video = highest views, or lexicographically smallest ID if tied
10 creator_best_video_index = defaultdict(int)
11
12 # Process each video
13 for index, (creator, video_id, view_count) in enumerate(zip(creators, ids, views)):
14 # Accumulate total views for this creator
15 creator_total_views[creator] += view_count
16
17 # Determine if this video should be the creator's best video
18 # Update if: 1) Creator not seen before, OR
19 # 2) Current video has more views than previous best, OR
20 # 3) Same views but lexicographically smaller ID
21 if (creator not in creator_best_video_index or
22 views[creator_best_video_index[creator]] < view_count or
23 (views[creator_best_video_index[creator]] == view_count and
24 ids[creator_best_video_index[creator]] > video_id)):
25 creator_best_video_index[creator] = index
26
27 # Find the maximum total views among all creators
28 max_total_views = max(creator_total_views.values())
29
30 # Return list of [creator_name, best_video_id] for creators with max total views
31 return [[creator, ids[creator_best_video_index[creator]]]
32 for creator, total_views in creator_total_views.items()
33 if total_views == max_total_views]
34
1class Solution {
2 public List<List<String>> mostPopularCreator(String[] creators, String[] ids, int[] views) {
3 int n = ids.length;
4
5 // Map to store total views for each creator
6 Map<String, Long> creatorTotalViews = new HashMap<>(n);
7
8 // Map to store the index of the most popular video for each creator
9 Map<String, Integer> creatorBestVideoIndex = new HashMap<>(n);
10
11 // Process each video
12 for (int i = 0; i < n; i++) {
13 String creator = creators[i];
14 String videoId = ids[i];
15 long videoViews = views[i];
16
17 // Update total views for this creator
18 creatorTotalViews.merge(creator, videoViews, Long::sum);
19
20 // Update the best video for this creator if:
21 // 1. This is the first video we've seen from this creator, OR
22 // 2. This video has more views than the current best, OR
23 // 3. This video has equal views but lexicographically smaller ID
24 if (!creatorBestVideoIndex.containsKey(creator) ||
25 views[creatorBestVideoIndex.get(creator)] < videoViews ||
26 (views[creatorBestVideoIndex.get(creator)] == videoViews &&
27 ids[creatorBestVideoIndex.get(creator)].compareTo(videoId) > 0)) {
28 creatorBestVideoIndex.put(creator, i);
29 }
30 }
31
32 // Find the maximum total views among all creators
33 long maxTotalViews = 0;
34 for (long totalViews : creatorTotalViews.values()) {
35 maxTotalViews = Math.max(maxTotalViews, totalViews);
36 }
37
38 // Build result list with creators having maximum total views
39 List<List<String>> result = new ArrayList<>();
40 for (Map.Entry<String, Long> entry : creatorTotalViews.entrySet()) {
41 if (entry.getValue() == maxTotalViews) {
42 String creator = entry.getKey();
43 int bestVideoIndex = creatorBestVideoIndex.get(creator);
44 result.add(List.of(creator, ids[bestVideoIndex]));
45 }
46 }
47
48 return result;
49 }
50}
51
1class Solution {
2public:
3 vector<vector<string>> mostPopularCreator(vector<string>& creators, vector<string>& ids, vector<int>& views) {
4 // Map to store total views for each creator
5 unordered_map<string, long long> creatorTotalViews;
6
7 // Map to store the index of the most popular video for each creator
8 unordered_map<string, int> creatorBestVideoIndex;
9
10 int n = ids.size();
11
12 // Process each video
13 for (int i = 0; i < n; ++i) {
14 string creator = creators[i];
15 string videoId = ids[i];
16 int viewCount = views[i];
17
18 // Update total views for this creator
19 creatorTotalViews[creator] += viewCount;
20
21 // Update the best video for this creator
22 // Choose video with highest views, or lexicographically smallest ID if tied
23 if (!creatorBestVideoIndex.count(creator) ||
24 views[creatorBestVideoIndex[creator]] < viewCount ||
25 (views[creatorBestVideoIndex[creator]] == viewCount &&
26 ids[creatorBestVideoIndex[creator]] > videoId)) {
27 creatorBestVideoIndex[creator] = i;
28 }
29 }
30
31 // Find the maximum total views among all creators
32 long long maxTotalViews = 0;
33 for (const auto& [creator, totalViews] : creatorTotalViews) {
34 maxTotalViews = max(maxTotalViews, totalViews);
35 }
36
37 // Collect all creators with maximum total views and their most popular videos
38 vector<vector<string>> result;
39 for (const auto& [creator, totalViews] : creatorTotalViews) {
40 if (totalViews == maxTotalViews) {
41 result.push_back({creator, ids[creatorBestVideoIndex[creator]]});
42 }
43 }
44
45 return result;
46 }
47};
48
1function mostPopularCreator(creators: string[], ids: string[], views: number[]): string[][] {
2 // Map to store total views for each creator
3 const creatorTotalViews: Map<string, number> = new Map();
4 // Map to store the index of the most popular video for each creator
5 const creatorBestVideoIndex: Map<string, number> = new Map();
6 const arrayLength = ids.length;
7
8 // Iterate through all videos to calculate total views and find best video per creator
9 for (let index = 0; index < arrayLength; ++index) {
10 const creator = creators[index];
11 const videoId = ids[index];
12 const videoViews = views[index];
13
14 // Update total views for the creator
15 creatorTotalViews.set(creator, (creatorTotalViews.get(creator) ?? 0) + videoViews);
16
17 // Check if this video should be the creator's most popular
18 // A video becomes the most popular if:
19 // 1. The creator has no previous best video, OR
20 // 2. This video has more views than the current best, OR
21 // 3. This video has same views but lexicographically smaller ID
22 if (!creatorBestVideoIndex.has(creator) ||
23 views[creatorBestVideoIndex.get(creator)!] < videoViews ||
24 (views[creatorBestVideoIndex.get(creator)!] === videoViews &&
25 ids[creatorBestVideoIndex.get(creator)!] > videoId)) {
26 creatorBestVideoIndex.set(creator, index);
27 }
28 }
29
30 // Find the maximum total views among all creators
31 const maxTotalViews = Math.max(...creatorTotalViews.values());
32 const result: string[][] = [];
33
34 // Collect all creators with maximum total views and their most popular video
35 for (const [creator, totalViews] of creatorTotalViews) {
36 if (totalViews === maxTotalViews) {
37 result.push([creator, ids[creatorBestVideoIndex.get(creator)!]]);
38 }
39 }
40
41 return result;
42}
43
Time and Space Complexity
The time complexity is O(n)
, where n
is the number of videos (length of the input arrays).
- The code iterates through all videos once using
zip(creators, ids, views)
, which takesO(n)
time - Inside the loop, dictionary operations (
cnt[c] += v
, checking/updatingd[c]
) areO(1)
on average - Finding the maximum value with
max(cnt.values())
takesO(m)
time wherem
is the number of unique creators, andm ≤ n
- The final list comprehension iterates through all unique creators
O(m)
and builds the result list - Overall:
O(n) + O(m) + O(m) = O(n)
sincem ≤ n
The space complexity is O(n)
.
- The
cnt
dictionary stores at mostm
unique creators with their total views, wherem ≤ n
, soO(m)
space - The
d
dictionary stores at mostm
unique creators with their video indices, soO(m)
space - The output list contains at most
m
creator-video pairs, soO(m)
space - In the worst case where all creators are unique,
m = n
- Overall:
O(m) = O(n)
in the worst case
Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Confusing Video ID with Video Index
The Problem: A common mistake is treating video IDs as unique identifiers when they're not. The problem explicitly states that different videos can have the same ID. This leads to incorrect logic where developers might try to use the ID as a key in a dictionary to track video information.
Incorrect Approach:
# WRONG: Using video ID as key
video_info = {}
for creator, video_id, view_count in zip(creators, ids, views):
video_info[video_id] = view_count # This overwrites data for duplicate IDs!
Correct Solution: Use the video's index position in the arrays as the unique identifier, not the video ID. Store indices in your tracking dictionaries and use them to reference back to the original arrays:
creator_best_video_index[creator] = index # Store index, not ID # Later retrieve the ID using: ids[creator_best_video_index[creator]]
Pitfall 2: Incorrect Lexicographic Comparison Logic
The Problem: When comparing videos with the same view count, the lexicographic comparison might be implemented backwards or at the wrong level of comparison.
Incorrect Approach:
# WRONG: Comparing current ID with stored ID incorrectly if views[stored_index] == view_count and video_id < ids[stored_index]: # This would keep updating unnecessarily
Correct Solution: Only update when the current video has strictly better criteria. The condition should check if the stored video's ID is lexicographically larger (worse) than the current one:
if views[stored_index] == view_count and ids[stored_index] > video_id: creator_best_video_index[creator] = index
Pitfall 3: Not Handling First Occurrence Properly
The Problem: Forgetting to handle the case when encountering a creator for the first time can lead to KeyError or incorrect comparisons.
Incorrect Approach:
# WRONG: Assumes creator already exists in dictionary if views[creator_best_video_index[creator]] < view_count: # KeyError if creator not in dict! creator_best_video_index[creator] = index
Correct Solution: Always check if the creator exists in the dictionary first, or use defaultdict with proper initialization:
if (creator not in creator_best_video_index or views[creator_best_video_index[creator]] < view_count or ...): creator_best_video_index[creator] = index
Pitfall 4: Returning Videos Instead of Video IDs
The Problem: The problem asks for the video ID in the result, not the video index or other information.
Incorrect Approach:
# WRONG: Returning the index instead of the ID return [[creator, creator_best_video_index[creator]] ...]
Correct Solution: Use the stored index to retrieve the actual video ID from the ids array:
return [[creator, ids[creator_best_video_index[creator]]] ...]
The three-steps of Depth First Search are:
- Identify states;
- Draw the state-space tree;
- DFS on the state-space tree.
Recommended Readings
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
https assets algo monster cover_photos heap svg Priority Queue and Heap What is the relationship between priority queue and heap Priority Queue is an Abstract Data Type and Heap is the concrete data structure we use to implement a priority queue Priority Queue A priority queue is a data structure
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Want a Structured Path to Master System Design Too? Don’t Miss This!