{x}
blog image

Design Video Sharing Platform

Solution Explanation for Design Video Sharing Platform

This problem requires designing a data structure to manage videos, their metadata (likes, dislikes, views), and associated video IDs. We need efficient ways to upload, remove, watch, like, dislike, and retrieve metadata.

Data Structures:

The most efficient approach uses a combination of data structures:

  1. HashMap (or Dictionary in Python): To map videoId to Video objects. This provides O(1) lookup for video retrieval based on videoId.

  2. HashSet (or Set in Python): To track available videoIds. This allows for O(1) lookup to find the smallest available ID when uploading a new video.

  3. Video Class: A custom class to encapsulate video data:

    • String video: The video content.
    • int views: Number of views.
    • int likes: Number of likes.
    • int dislikes: Number of dislikes.

Algorithm:

  • upload(String video):

    • Find the smallest available videoId from the HashSet.
    • Create a new Video object with the provided video content, and initialize views, likes, and dislikes to 0.
    • Add the videoId and Video object to the HashMap.
    • Remove the videoId from the HashSet (it's no longer available).
    • Return the videoId.
  • remove(int videoId):

    • If the videoId exists in the HashMap, remove the corresponding Video object.
    • Add the videoId back to the HashSet (making it available).
  • watch(int videoId, int startMinute, int endMinute):

    • If the videoId exists in the HashMap:
      • Increment the views count.
      • Extract the substring of the video from startMinute to min(endMinute, video.length() - 1).
      • Return the substring.
    • Otherwise, return "-1".
  • like(int videoId), dislike(int videoId):

    • If the videoId exists in the HashMap, increment the respective counter (likes or dislikes).
  • getLikesAndDislikes(int videoId):

    • If the videoId exists, return an array [likes, dislikes].
    • Otherwise, return [-1].
  • getViews(int videoId):

    • If the videoId exists, return the views count.
    • Otherwise, return -1.

Time Complexity Analysis:

  • upload: O(1) on average (HashSet and HashMap operations). Worst-case O(n) if the HashSet needs to resize.
  • remove: O(1) on average.
  • watch: O(m) where m is the length of the substring returned (which is bounded by endMinute - startMinute). In the worst case it's O(n), where n is video length.
  • like, dislike: O(1).
  • getLikesAndDislikes, getViews: O(1).

Space Complexity Analysis:

The space complexity is O(N), where N is the total number of videos uploaded. This is due to the storage of videos in the HashMap.

Code (Java):

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
 
class VideoSharingPlatform {
    HashMap<Integer, Video> videos;
    Set<Integer> availableVideoIds;
 
    public VideoSharingPlatform() {
        videos = new HashMap<>();
        availableVideoIds = new HashSet<>();
    }
 
    public int upload(String video) {
        int videoId = 0;
        while (availableVideoIds.contains(videoId) || videos.containsKey(videoId)) {
            videoId++;
        }
        availableVideoIds.remove(videoId);
        videos.put(videoId, new Video(video));
        return videoId;
    }
 
    public void remove(int videoId) {
        if (videos.containsKey(videoId)) {
            availableVideoIds.add(videoId);
            videos.remove(videoId);
        }
    }
 
    public String watch(int videoId, int startMinute, int endMinute) {
        if (videos.containsKey(videoId)) {
            Video video = videos.get(videoId);
            video.views++;
            int end = Math.min(endMinute, video.video.length() - 1);
            return video.video.substring(startMinute, end + 1);
        }
        return "-1";
    }
 
    public void like(int videoId) {
        if (videos.containsKey(videoId)) {
            videos.get(videoId).likes++;
        }
    }
 
    public void dislike(int videoId) {
        if (videos.containsKey(videoId)) {
            videos.get(videoId).dislikes++;
        }
    }
 
    public int[] getLikesAndDislikes(int videoId) {
        if (videos.containsKey(videoId)) {
            Video video = videos.get(videoId);
            return new int[]{video.likes, video.dislikes};
        }
        return new int[]{-1};
    }
 
    public int getViews(int videoId) {
        if (videos.containsKey(videoId)) {
            return videos.get(videoId).views;
        }
        return -1;
    }
 
 
    static class Video {
        String video;
        int views;
        int likes;
        int dislikes;
 
        public Video(String video) {
            this.video = video;
            this.views = 0;
            this.likes = 0;
            this.dislikes = 0;
        }
    }
 
    public static void main(String[] args){
        VideoSharingPlatform v = new VideoSharingPlatform();
        System.out.println(v.upload("123")); //0
        System.out.println(v.upload("456")); //1
        v.remove(4);
        v.remove(0);
        System.out.println(v.upload("789")); //0
        System.out.println(v.watch(1,0,5)); //456
        System.out.println(v.watch(1,0,1)); //45
        v.like(1);
        v.dislike(1);
        v.dislike(1);
        System.out.println(java.util.Arrays.toString(v.getLikesAndDislikes(1))); //[1,2]
        System.out.println(v.getViews(1)); //2
 
 
    }
}

Similar implementations can be done in Python, C++, and Go using their respective dictionary/hashmap and set equivalents. The core logic and complexity remain consistent across languages.