Skip to content

Commit b74ca41

Browse files
committed
Add solution #3369
1 parent d2ae3bc commit b74ca41

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2673,6 +2673,7 @@
26732673
3356|[Zero Array Transformation II](./solutions/3356-zero-array-transformation-ii.js)|Medium|
26742674
3359|[Find Sorted Submatrices With Maximum Element at Most K](./solutions/3359-find-sorted-submatrices-with-maximum-element-at-most-k.js)|Hard|
26752675
3362|[Zero Array Transformation III](./solutions/3362-zero-array-transformation-iii.js)|Medium|
2676+
3369|[Design an Array Statistics Tracker](./solutions/3369-design-an-array-statistics-tracker.js)|Hard|
26762677
3372|[Maximize the Number of Target Nodes After Connecting Trees I](./solutions/3372-maximize-the-number-of-target-nodes-after-connecting-trees-i.js)|Medium|
26772678
3373|[Maximize the Number of Target Nodes After Connecting Trees II](./solutions/3373-maximize-the-number-of-target-nodes-after-connecting-trees-ii.js)|Hard|
26782679
3375|[Minimum Operations to Make Array Values Equal to K](./solutions/3375-minimum-operations-to-make-array-values-equal-to-k.js)|Easy|
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/**
2+
* 3369. Design an Array Statistics Tracker
3+
* https://leetcode.com/problems/design-an-array-statistics-tracker/
4+
* Difficulty: Hard
5+
*
6+
* Design a data structure that keeps track of the values in it and answers some queries regarding
7+
* their mean, median, and mode.
8+
*
9+
* Implement the StatisticsTracker class.
10+
* - StatisticsTracker(): Initialize the StatisticsTracker object with an empty array.
11+
* - void addNumber(int number): Add number to the data structure.
12+
* - void removeFirstAddedNumber(): Remove the earliest added number from the data structure.
13+
* - int getMean(): Return the floored mean of the numbers in the data structure.
14+
* - int getMedian(): Return the median of the numbers in the data structure.
15+
* - int getMode(): Return the mode of the numbers in the data structure. If there are multiple
16+
* modes, return the smallest one.
17+
*
18+
* Note:
19+
* - The mean of an array is the sum of all the values divided by the number of values in the array.
20+
* - The median of an array is the middle element of the array when it is sorted in non-decreasing
21+
* order. If there are two choices for a median, the larger of the two values is taken.
22+
* - The mode of an array is the element that appears most often in the array.
23+
*/
24+
25+
var StatisticsTracker = function() {
26+
this.deque = [];
27+
this.count = new Map();
28+
this.frequencyHeap = new PriorityQueue((a, b) => {
29+
if (a[0] !== b[0]) return b[0] - a[0];
30+
return a[1] - b[1];
31+
});
32+
this.total = 0;
33+
34+
this.smallHeap = new PriorityQueue((a, b) => b - a);
35+
this.largeHeap = new PriorityQueue((a, b) => a - b);
36+
this.largeRemove = new Map();
37+
this.smallRemove = new Map();
38+
this.balance = 0;
39+
};
40+
41+
/**
42+
* @param {number} number
43+
* @return {void}
44+
*/
45+
StatisticsTracker.prototype.addNumber = function(number) {
46+
this.deque.push(number);
47+
this.total += number;
48+
49+
const currentCount = this.count.get(number) || 0;
50+
this.count.set(number, currentCount + 1);
51+
this.frequencyHeap.enqueue([this.count.get(number), number]);
52+
53+
if (this.largeHeap.isEmpty() || number >= this.largeHeap.front()) {
54+
this.largeHeap.enqueue(number);
55+
this.balance += 1;
56+
} else {
57+
this.smallHeap.enqueue(number);
58+
this.balance -= 1;
59+
}
60+
61+
this.keepBalance();
62+
};
63+
64+
/**
65+
* @return {void}
66+
*/
67+
StatisticsTracker.prototype.removeFirstAddedNumber = function() {
68+
const value = this.deque.shift();
69+
70+
const currentCount = this.count.get(value);
71+
this.count.set(value, currentCount - 1);
72+
if (this.count.get(value) > 0) {
73+
this.frequencyHeap.enqueue([this.count.get(value), value]);
74+
}
75+
76+
this.total -= value;
77+
78+
if (!this.largeHeap.isEmpty() && value >= this.largeHeap.front()) {
79+
this.largeRemove.set(value, (this.largeRemove.get(value) || 0) + 1);
80+
this.balance -= 1;
81+
} else {
82+
this.smallRemove.set(value, (this.smallRemove.get(value) || 0) + 1);
83+
this.balance += 1;
84+
}
85+
86+
this.keepBalance();
87+
};
88+
89+
/**
90+
* @return {void}
91+
*/
92+
StatisticsTracker.prototype.keepBalance = function() {
93+
if (this.balance > 1) {
94+
this.smallHeap.enqueue(this.largeHeap.dequeue());
95+
this.balance -= 2;
96+
}
97+
if (this.balance < 0) {
98+
this.largeHeap.enqueue(this.smallHeap.dequeue());
99+
this.balance += 2;
100+
}
101+
102+
while (!this.smallHeap.isEmpty() && (this.smallRemove.get(this.smallHeap.front()) || 0) > 0) {
103+
const removed = this.smallHeap.dequeue();
104+
this.smallRemove.set(removed, this.smallRemove.get(removed) - 1);
105+
}
106+
107+
while (!this.largeHeap.isEmpty() && (this.largeRemove.get(this.largeHeap.front()) || 0) > 0) {
108+
const removed = this.largeHeap.dequeue();
109+
this.largeRemove.set(removed, this.largeRemove.get(removed) - 1);
110+
}
111+
};
112+
113+
/**
114+
* @return {number}
115+
*/
116+
StatisticsTracker.prototype.getMean = function() {
117+
return Math.floor(this.total / this.deque.length);
118+
};
119+
120+
/**
121+
* @return {number}
122+
*/
123+
StatisticsTracker.prototype.getMedian = function() {
124+
return this.largeHeap.front();
125+
};
126+
127+
/**
128+
* @return {number}
129+
*/
130+
StatisticsTracker.prototype.getMode = function() {
131+
while (!this.frequencyHeap.isEmpty()) {
132+
const [frequency, value] = this.frequencyHeap.front();
133+
if (this.count.get(value) === frequency) {
134+
return value;
135+
} else {
136+
this.frequencyHeap.dequeue();
137+
}
138+
}
139+
};

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy