Skip to main content

Kth Largest Element in a Stream

Problem statement

Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Implement KthLargest class:

  • KthLargest(int k, int[] nums) Initializes the object with the integer k and the stream of integers nums.
  • int add(int val) Appends the integer val to the stream and returns the element representing the kth largest element in the stream.

Example 1:

Input["KthLargest", "add", "add", "add", "add", "add"][[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]Output[null, 4, 5, 5, 8, 8]ExplanationKthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);kthLargest.add(3);   // return 4kthLargest.add(5);   // return 5kthLargest.add(10);  // return 5kthLargest.add(9);   // return 8kthLargest.add(4);   // return 8

Constraints:

  • 1 <= k <= 104
  • 0 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • -104 <= val <= 104
  • At most 104 calls will be made to add.
  • It is guaranteed that there will be at least k elements in the array when you search for the kth element.

My solution

/**
* @param {number} k
* @param {number[]} nums
*/
var KthLargest = function(k, nums) {
this.k = k;
this.nums = nums.sort((a, b) => a - b);

};

/**
* @param {number} val
* @return {number}
*/
KthLargest.prototype.add = function(val) {
let left = 0;
let right = this.nums.length - 1;
let indexToInsert = left;
while(left <= right) {
let mid = Math.floor(left + (right - left) / 2);
if (val > this.nums[mid]) {
left = mid + 1;
indexToInsert = mid + 1;
} else if (val < this.nums[mid]) {
right = mid - 1;
indexToInsert = mid;
} else {
indexToInsert = mid
break;
}
}

this.nums.splice(indexToInsert, 0, val);
return this.nums[this.nums.length - this.k];
};

/**
* Your KthLargest object will be instantiated and called as such:
* var obj = new KthLargest(k, nums)
* var param_1 = obj.add(val)
*/