Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Finding MK Average

Updated
4 min read

Introduction

In this blog post, we will explore how to solve the LeetCode problem "1825" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.

Problem Statement

You are given two integers, m and k, and a stream of integers. You are tasked to implement a data structure that calculates the MKAverage for the stream. The MKAverage can be calculated using these steps: If the number of the elements in the stream is less than m you should consider the MKAverage to be -1. Otherwise, copy the last m elements of the stream to a separate container. Remove the smallest k elements and the largest k elements from the container. Calculate the average value for the rest of the elements rounded down to the nearest integer. Implement the MKAverage class: MKAverage(int m, int k) Initializes the MKAverage object with an empty stream and the two integers m and k. void addElement(int num) Inserts a new element num into the stream. int calculateMKAverage() Calculates and returns the MKAverage for the current stream rounded down to the nearest integer. Example 1: Input ["MKAverage", "addElement", "addElement", "calculateMKAverage", "addElement", "calculateMKAverage", "addElement", "addElement", "addElement", "calculateMKAverage"] [[3, 1], [3], [1], [], [10], [], [5], [5], [5], []] Output [null, null, null, -1, null, 3, null, null, null, 5] Explanation MKAverage obj = new MKAverage(3, 1); obj.addElement(3); // current elements are [3] obj.addElement(1); // current elements are [3,1] obj.calculateMKAverage(); // return -1, because m = 3 and only 2 elements exist. obj.addElement(10); // current elements are [3,1,10] obj.calculateMKAverage(); // The last 3 elements are [3,1,10]. // After removing smallest and largest 1 element the container will be [3]. // The average of [3] equals 3/1 = 3, return 3 obj.addElement(5); // current elements are [3,1,10,5] obj.addElement(5); // current elements are [3,1,10,5,5] obj.addElement(5); // current elements are [3,1,10,5,5,5] obj.calculateMKAverage(); // The last 3 elements are [5,5,5]. // After removing smallest and largest 1 element the container will be [5]. // The average of [5] equals 5/1 = 5, return 5 Constraints: 3 <= m <= 105 1 <= k*2 < m 1 <= num <= 105 At most 105 calls will be made to addElement and calculateMKAverage.

Explanation

Here's a breakdown of the solution, followed by the Python code:

  • Maintain a Deque: Use a double-ended queue (deque) to efficiently store the last m elements of the stream. This allows for O(1) addition and removal from both ends.
  • Sorted Structures for Calculation: Employ sorted lists (using SortedList from the sortedcontainers library for efficient insertion, deletion, and retrieval) to track the k smallest, k largest, and remaining middle elements. This allows for fast updates and average calculation.
  • Update Sorted Structures on Addition/Removal: When a new element is added, update the sorted lists by potentially moving elements between them to maintain their correct sizes and sorted order. When an element is removed from the deque, perform similar updates.

  • Runtime Complexity: O(log m) for addElement and calculateMKAverage. Storage Complexity: O(m).

Code

    from collections import deque
from sortedcontainers import SortedList

class MKAverage:
    def __init__(self, m: int, k: int):
        self.m = m
        self.k = k
        self.stream = deque()
        self.smallest = SortedList()
        self.largest = SortedList()
        self.middle = SortedList()
        self.sum_middle = 0

    def addElement(self, num: int) -> None:
        self.stream.append(num)

        if len(self.stream) <= self.m:
            self.middle.add(num)
            self.sum_middle += num
        else:
            self.stream.popleft()
            removed_num = self.middle[0]

            self.middle.discard(removed_num)
            self.sum_middle -= removed_num
            self.middle.add(num)
            self.sum_middle += num

        if len(self.stream) >= self.m:
            while len(self.smallest) < self.k:
                val = self.middle.pop(0)
                self.smallest.add(val)
                self.sum_middle -= val

            while len(self.largest) < self.k:
                val = self.middle.pop()
                self.largest.add(val)
                self.sum_middle -= val

            while self.smallest and self.middle and self.smallest[-1] > self.middle[0]:
                val1 = self.smallest.pop()
                val2 = self.middle.pop(0)
                self.smallest.add(val2)
                self.middle.add(val1)
                self.sum_middle += (val1 - val2)

            while self.largest and self.middle and self.largest[0] < self.middle[-1]:
                val1 = self.largest.pop(0)
                val2 = self.middle.pop()
                self.largest.add(val2)
                self.middle.add(val1)
                self.sum_middle += (val1 - val2)

    def calculateMKAverage(self) -> int:
        if len(self.stream) < self.m:
            return -1

        return self.sum_middle // (self.m - 2 * self.k)

More from this blog

C

Chatmagic blog

2894 posts