101 Logo
onenoughtone

Code Implementation

Stream Data Processor Implementation

Below is the implementation of the stream data processor:

solution.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/**
* Brute Force Approach
* Time Complexity: O(n) for add operation
* Space Complexity: O(n) for storing all elements
*/
class KthLargestBruteForce {
/**
* @param {number} k
* @param {number[]} nums
*/
constructor(k, nums) {
this.k = k;
this.nums = nums.sort((a, b) => b - a); // Sort in descending order
}
/**
* @param {number} val
* @return {number}
*/
add(val) {
// Insert val into the correct position to maintain sorted order
let i = 0;
while (i < this.nums.length && this.nums[i] > val) {
i++;
}
this.nums.splice(i, 0, val);
// Return the kth largest element
return this.nums[this.k - 1];
}
}
/**
* Min Heap Approach
* Time Complexity: O(log k) for add operation
* Space Complexity: O(k) for storing k elements
*
* Note: JavaScript doesn't have a built-in heap, so we'll implement a simple min heap
*/
class MinHeap {
constructor() {
this.heap = [];
}
size() {
return this.heap.length;
}
peek() {
return this.heap[0];
}
add(val) {
this.heap.push(val);
this.bubbleUp(this.heap.length - 1);
}
poll() {
if (this.heap.length === 0) {
return null;
}
const min = this.heap[0];
const last = this.heap.pop();
if (this.heap.length > 0) {
this.heap[0] = last;
this.bubbleDown(0);
}
return min;
}
bubbleUp(index) {
while (index > 0) {
const parentIndex = Math.floor((index - 1) / 2);
if (this.heap[parentIndex] <= this.heap[index]) {
break;
}
// Swap parent and current element
[this.heap[parentIndex], this.heap[index]] = [this.heap[index], this.heap[parentIndex]];
index = parentIndex;
}
}
bubbleDown(index) {
const lastIndex = this.heap.length - 1;
while (true) {
const leftChildIndex = 2 * index + 1;
const rightChildIndex = 2 * index + 2;
let smallestIndex = index;
if (leftChildIndex <= lastIndex && this.heap[leftChildIndex] < this.heap[smallestIndex]) {
smallestIndex = leftChildIndex;
}
if (rightChildIndex <= lastIndex && this.heap[rightChildIndex] < this.heap[smallestIndex]) {
smallestIndex = rightChildIndex;
}
if (smallestIndex === index) {
break;
}
// Swap current element with the smallest child
[this.heap[index], this.heap[smallestIndex]] = [this.heap[smallestIndex], this.heap[index]];
index = smallestIndex;
}
}
}
class KthLargest {
/**
* @param {number} k
* @param {number[]} nums
*/
constructor(k, nums) {
this.k = k;
this.heap = new MinHeap();
// Add all elements from nums to the heap
for (const num of nums) {
this.add(num);
}
}
/**
* @param {number} val
* @return {number}
*/
add(val) {
this.heap.add(val);
// If heap size exceeds k, remove the smallest element
if (this.heap.size() > this.k) {
this.heap.poll();
}
// Return the kth largest element (the root of the heap)
return this.heap.peek();
}
}
// Test case
const kthLargest = new KthLargest(3, [4, 5, 8, 2]);
console.log(kthLargest.add(3)); // 4
console.log(kthLargest.add(5)); // 5
console.log(kthLargest.add(10)); // 5
console.log(kthLargest.add(9)); // 8
console.log(kthLargest.add(4)); // 8

Step-by-Step Explanation

Let's break down the implementation:

  1. 1. Understand the Problem: First, understand that we need to design a class that finds the kth largest element in a stream of numbers.
  2. 2. Choose an Approach: Decide which approach to use: brute force (maintain a sorted list) or min heap (maintain a heap of size k).
  3. 3. Implement the Constructor: Initialize the class with the given k and nums array, setting up the data structure (sorted list or min heap).
  4. 4. Implement the Add Method: Add the new element to the data structure and return the kth largest element.
  5. 5. Handle Edge Cases: Consider edge cases such as empty arrays, k = 1, or when the number of elements is less than k.
  6. 6. Optimize the Solution: Consider optimizations such as using a min heap for O(log k) time complexity instead of maintaining a sorted list.
  7. 7. Test the Solution: Verify the solution with the provided examples and additional test cases.
ProblemSolutionCode
101 Logo
onenoughtone