LeetCode 2456 - Most Popular Video Creator

The problem gives us three parallel arrays: - creators[i] represents the creator of the ith video - ids[i] represents the video ID of the ith video - views[i] represents the number of views for the ith video Each index corresponds to one video.

LeetCode Problem 2456

Difficulty: 🟡 Medium
Topics: Array, Hash Table, String, Sorting, Heap (Priority Queue)

Solution

Problem Understanding

The problem gives us three parallel arrays:

  • creators[i] represents the creator of the ith video
  • ids[i] represents the video ID of the ith video
  • views[i] represents the number of views for the ith video

Each index corresponds to one video. Multiple videos can belong to the same creator, and different videos may even share the same ID. IDs are not guaranteed to be unique.

The popularity of a creator is defined as the sum of views across all of their videos. We must determine which creator or creators have the highest total popularity.

For every creator with maximum popularity, we also need to determine their most viewed video:

  • Choose the video with the highest number of views
  • If multiple videos have the same highest view count, choose the lexicographically smallest ID

The final answer is a list of pairs:

[creator_name, most_popular_video_id]

The order of the returned pairs does not matter.

The constraints are important:

  • n can be as large as 10^5
  • A quadratic solution would be too slow
  • We need something close to linear time
  • Hash maps are a natural fit because we need to group videos by creator efficiently

There are several important edge cases to keep in mind:

  • Multiple creators can tie for maximum popularity
  • Multiple videos of the same creator can tie for maximum views
  • Lexicographical comparison must be handled correctly
  • Videos may have duplicate IDs
  • View counts may be zero
  • A creator may only have one video

A naive implementation can easily fail on tie-breaking logic, especially when multiple videos have equal view counts.

Approaches

Brute Force Approach

A brute force solution would process each creator independently.

For every unique creator, we could:

  1. Scan the entire input to calculate their total popularity
  2. Scan the entire input again to find their most viewed video
  3. Track the global maximum popularity
  4. Build the final result

This approach is correct because it explicitly examines all videos for every creator. However, it is inefficient because repeated full-array scans lead to excessive work.

If there are k unique creators and n videos, the complexity becomes approximately O(k * n). In the worst case, every video belongs to a different creator, so k = n, resulting in O(n^2) time complexity.

With n = 10^5, this is far too slow.

Optimal Approach

The key insight is that all required information can be collected in a single traversal.

For every creator, we need to maintain:

  • Total popularity
  • Highest individual video views
  • Corresponding best video ID

A hash map allows us to update all of this information efficiently while iterating once through the arrays.

During traversal:

  • Add current views to the creator's total popularity

  • Compare the current video against the creator's best video

  • Update the best video if:

  • The current video has more views, or

  • The current video has equal views but lexicographically smaller ID

After processing all videos, we perform another pass over the creators stored in the hash map to determine which creators have maximum popularity.

This gives us linear time complexity.

Approach Time Complexity Space Complexity Notes
Brute Force O(n²) O(n) Repeatedly scans the arrays for each creator
Optimal O(n) O(n) Single-pass aggregation using hash maps

Algorithm Walkthrough

  1. Create a hash map to store information for each creator.

For every creator, we need:

  • Total popularity
  • Highest video view count
  • Best video ID

Conceptually:

creator -> [total_views, max_video_views, best_video_id]
  1. Iterate through all videos once.

For each index i:

  • Read:

  • creator = creators[i]

  • video_id = ids[i]

  • view_count = views[i]

  1. Update the creator's total popularity.

Add view_count to the creator's accumulated total. 4. Update the creator's best video.

Compare the current video with the stored best video:

  • If current views are larger, replace the best video
  • If views are equal and current ID is lexicographically smaller, replace the best video

This guarantees correct tie-breaking. 5. Track the global maximum popularity.

While updating creator totals, maintain the largest popularity seen so far. 6. Build the final answer.

Iterate through all creators in the hash map:

  • If a creator's popularity equals the global maximum:

  • Add [creator, best_video_id] to the result

  1. Return the result list.

Why it works

The algorithm works because every creator's statistics are updated consistently during traversal.

At any moment:

  • The stored total popularity equals the sum of all processed videos for that creator

  • The stored best video always satisfies:

  • Maximum views among processed videos

  • Lexicographically smallest ID among tied videos

After the full traversal, the stored information is complete and correct for every creator. Selecting creators with maximum popularity therefore produces the correct final answer.

Python Solution

from typing import List
from collections import defaultdict

class Solution:
    def mostPopularCreator(
        self,
        creators: List[str],
        ids: List[str],
        views: List[int]
    ) -> List[List[str]]:
        
        creator_data = {}
        max_popularity = 0

        for creator, video_id, view_count in zip(creators, ids, views):

            if creator not in creator_data:
                creator_data[creator] = [
                    0,              # total popularity
                    view_count,     # max video views
                    video_id        # best video id
                ]

            creator_data[creator][0] += view_count

            current_max_views = creator_data[creator][1]
            current_best_id = creator_data[creator][2]

            if (
                view_count > current_max_views or
                (
                    view_count == current_max_views and
                    video_id < current_best_id
                )
            ):
                creator_data[creator][1] = view_count
                creator_data[creator][2] = video_id

            max_popularity = max(
                max_popularity,
                creator_data[creator][0]
            )

        result = []

        for creator, data in creator_data.items():
            total_views, _, best_video_id = data

            if total_views == max_popularity:
                result.append([creator, best_video_id])

        return result

The implementation uses a dictionary named creator_data to aggregate all information about each creator.

Each creator stores three values:

  • Total popularity
  • Maximum video view count
  • Best video ID

The main loop processes each video exactly once. During this traversal:

  • Popularity totals are updated
  • Best video selection is maintained using the tie-breaking rules
  • Global maximum popularity is updated incrementally

The lexicographical comparison is handled naturally using Python string comparison. Since Python compares strings lexicographically by default, the condition:

video_id < current_best_id

correctly implements the problem requirement.

Finally, the second loop filters creators whose popularity equals the global maximum and constructs the result list.

Go Solution

func mostPopularCreator(creators []string, ids []string, views []int) [][]string {

	type CreatorInfo struct {
		totalViews int64
		maxViews   int
		bestID     string
	}

	creatorData := make(map[string]*CreatorInfo)
	var maxPopularity int64 = 0

	for i := 0; i < len(creators); i++ {

		creator := creators[i]
		videoID := ids[i]
		viewCount := views[i]

		if _, exists := creatorData[creator]; !exists {
			creatorData[creator] = &CreatorInfo{
				totalViews: 0,
				maxViews:   viewCount,
				bestID:     videoID,
			}
		}

		info := creatorData[creator]

		info.totalViews += int64(viewCount)

		if viewCount > info.maxViews ||
			(viewCount == info.maxViews && videoID < info.bestID) {

			info.maxViews = viewCount
			info.bestID = videoID
		}

		if info.totalViews > maxPopularity {
			maxPopularity = info.totalViews
		}
	}

	result := [][]string{}

	for creator, info := range creatorData {
		if info.totalViews == maxPopularity {
			result = append(result, []string{
				creator,
				info.bestID,
			})
		}
	}

	return result
}

The Go implementation follows the same logic as the Python solution but uses a struct to store creator information.

One important Go-specific detail is the use of int64 for total popularity. Although individual views fit within int, the sum can exceed standard 32-bit integer limits because:

10^5 videos * 10^5 views = 10^10

Using int64 prevents overflow issues.

The result slice is initialized as an empty slice rather than nil, which is perfectly acceptable for LeetCode submissions.

Worked Examples

Example 1

creators = ["alice","bob","alice","chris"]
ids = ["one","two","three","four"]
views = [5,10,5,4]

Iteration Trace

Step Creator ID Views Total Popularity Best Video
1 alice one 5 alice = 5 one
2 bob two 10 bob = 10 two
3 alice three 5 alice = 10 one
4 chris four 4 chris = 4 four

After processing:

alice -> total = 10, best = "one"
bob -> total = 10, best = "two"
chris -> total = 4, best = "four"

Maximum popularity:

10

Creators with popularity 10:

["alice", "one"]
["bob", "two"]

Final answer:

[["alice","one"],["bob","two"]]

Example 2

creators = ["alice","alice","alice"]
ids = ["a","b","c"]
views = [1,2,2]

Iteration Trace

Step Creator ID Views Total Popularity Best Video
1 alice a 1 1 a
2 alice b 2 3 b
3 alice c 2 5 b

At step 3:

  • "c" has the same views as "b"
  • "b" is lexicographically smaller
  • Therefore "b" remains the best video

Final creator state:

alice -> total = 5, best = "b"

Final answer:

[["alice","b"]]

Complexity Analysis

Measure Complexity Explanation
Time O(n) Each video is processed once, and creators are scanned once more
Space O(n) Hash map stores information for each unique creator

The algorithm performs a constant amount of work per video during the main traversal. The second pass iterates over unique creators, which is at most n.

The space complexity is linear because the hash map may store an entry for every creator in the worst case.

Test Cases

sol = Solution()

# Example 1
assert sorted(sol.mostPopularCreator(
    ["alice", "bob", "alice", "chris"],
    ["one", "two", "three", "four"],
    [5, 10, 5, 4]
)) == sorted([["alice", "one"], ["bob", "two"]])

# Example 2
assert sol.mostPopularCreator(
    ["alice", "alice", "alice"],
    ["a", "b", "c"],
    [1, 2, 2]
) == [["alice", "b"]]

# Single creator, single video
assert sol.mostPopularCreator(
    ["alice"],
    ["vid"],
    [100]
) == [["alice", "vid"]]

# Tie in creator popularity
assert sorted(sol.mostPopularCreator(
    ["a", "b"],
    ["x", "y"],
    [10, 10]
)) == sorted([["a", "x"], ["b", "y"]])

# Tie in video views, lexicographical tie-break
assert sol.mostPopularCreator(
    ["alice", "alice"],
    ["zzz", "aaa"],
    [5, 5]
) == [["alice", "aaa"]]

# Duplicate video IDs
assert sol.mostPopularCreator(
    ["alice", "alice"],
    ["same", "same"],
    [3, 10]
) == [["alice", "same"]]

# Zero views
assert sorted(sol.mostPopularCreator(
    ["a", "b"],
    ["x", "y"],
    [0, 0]
)) == sorted([["a", "x"], ["b", "y"]])

# Larger mixed example
assert sorted(sol.mostPopularCreator(
    ["a", "b", "a", "c", "b"],
    ["v1", "v2", "v3", "v4", "v5"],
    [100, 50, 200, 10, 250]
)) == [["b", "v5"]]

# Multiple equal max videos with smallest lexicographical choice
assert sol.mostPopularCreator(
    ["x", "x", "x"],
    ["cat", "apple", "banana"],
    [7, 7, 7]
) == [["x", "apple"]]
Test Why
Example 1 Validates multiple creators tying for popularity
Example 2 Validates lexicographical tie-breaking
Single creator Smallest valid input
Tie in popularity Ensures all maximum creators are returned
Tie in video views Ensures lexicographical comparison works
Duplicate IDs Confirms IDs are not assumed unique
Zero views Tests minimum view counts
Larger mixed example Tests general aggregation correctness
Equal max videos Verifies repeated tie-breaking behavior

Edge Cases

Multiple Creators With Equal Popularity

One common bug is returning only a single creator with maximum popularity. The problem explicitly requires returning all creators tied for the highest popularity.

For example:

alice -> 10 views
bob -> 10 views

Both creators must appear in the output. The implementation handles this by first computing the global maximum popularity, then collecting every creator whose popularity matches it.

Multiple Videos With Equal Maximum Views

Another subtle edge case occurs when a creator has multiple videos tied for highest views.

For example:

IDs = ["zzz", "aaa"]
Views = [5, 5]

The correct answer is "aaa" because it is lexicographically smaller.

A naive implementation that only updates on strictly larger views would incorrectly keep "zzz". The solution explicitly handles equal-view tie-breaking with lexicographical comparison.

Duplicate Video IDs

The problem states that IDs are not unique. Two different videos may share the same ID.

For example:

ids = ["same", "same"]
views = [3, 10]

A buggy implementation might assume IDs uniquely identify videos and accidentally overwrite information.

This solution never uses IDs as hash map keys. IDs are treated purely as strings associated with videos, so duplicate IDs are handled naturally and correctly.