Solving Leetcode Interviews in Seconds with AI: Finding MK Average
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
melements of the stream. This allows for O(1) addition and removal from both ends. - Sorted Structures for Calculation: Employ sorted lists (using
SortedListfrom thesortedcontainerslibrary for efficient insertion, deletion, and retrieval) to track theksmallest,klargest, 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
addElementandcalculateMKAverage. 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)