Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 92af611

Browse files
rain84yanglbme
andauthored
feat: add solutions to lc problem: No.0295 (doocs#3166)
Co-authored-by: Libin YANG <contact@yanglibin.info>
1 parent 43a0d90 commit 92af611

File tree

11 files changed

+657
-452
lines changed

11 files changed

+657
-452
lines changed

‎solution/0200-0299/0295.Find Median from Data Stream/README.md‎

Lines changed: 220 additions & 154 deletions
Large diffs are not rendered by default.

‎solution/0200-0299/0295.Find Median from Data Stream/README_EN.md‎

Lines changed: 224 additions & 148 deletions
Large diffs are not rendered by default.
Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,31 @@
11
class MedianFinder {
22
public:
3-
/** initialize your data structure here. */
43
MedianFinder() {
54
}
65

76
void addNum(int num) {
8-
q1.push(num);
9-
q2.push(q1.top());
10-
q1.pop();
11-
if (q2.size() - q1.size() > 1) {
12-
q1.push(q2.top());
13-
q2.pop();
7+
maxQ.push(num);
8+
minQ.push(maxQ.top());
9+
maxQ.pop();
10+
11+
if (minQ.size() > maxQ.size() + 1) {
12+
maxQ.push(minQ.top());
13+
minQ.pop();
1414
}
1515
}
1616

1717
double findMedian() {
18-
if (q2.size() > q1.size()) {
19-
return q2.top();
20-
}
21-
return (double) (q1.top() + q2.top()) / 2;
18+
return minQ.size() == maxQ.size() ? (minQ.top() + maxQ.top()) / 2.0 : minQ.top();
2219
}
2320

2421
private:
25-
priority_queue<int, vector<int>, greater<int>> q1;
26-
priority_queue<int> q2;
22+
priority_queue<int> maxQ;
23+
priority_queue<int, vector<int>, greater<int>> minQ;
2724
};
2825

2926
/**
3027
* Your MedianFinder object will be instantiated and called as such:
3128
* MedianFinder* obj = new MedianFinder();
3229
* obj->addNum(num);
3330
* double param_2 = obj->findMedian();
34-
*/
31+
*/

‎solution/0200-0299/0295.Find Median from Data Stream/Solution.cs‎

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,21 @@
11
public class MedianFinder {
2-
private List<int>nums;
3-
private intcurIndex;
2+
private PriorityQueue<int,int>minQ=newPriorityQueue<int,int>();
3+
private PriorityQueue<int,int>maxQ=newPriorityQueue<int,int>(Comparer<int>.Create((a,b)=>b.CompareTo(a)));
44

5-
/** initialize your data structure here. */
65
public MedianFinder() {
7-
nums = new List<int>();
8-
}
96

10-
private int FindIndex(int val) {
11-
int left = 0;
12-
int right = nums.Count - 1;
13-
while (left <= right) {
14-
int mid = left + (right - left) / 2;
15-
if (val > nums[mid]) {
16-
left = mid + 1;
17-
} else {
18-
right = mid - 1;
19-
}
20-
}
21-
return left;
227
}
238

249
public void AddNum(int num) {
25-
if (nums.Count == 0) {
26-
nums.Add(num);
27-
curIndex = 0;
28-
} else {
29-
curIndex = FindIndex(num);
30-
if (curIndex == nums.Count) {
31-
nums.Add(num);
32-
} else {
33-
nums.Insert(curIndex, num);
34-
}
10+
maxQ.Enqueue(num, num);
11+
minQ.Enqueue(maxQ.Peek(), maxQ.Dequeue());
12+
if (minQ.Count > maxQ.Count + 1) {
13+
maxQ.Enqueue(minQ.Peek(), minQ.Dequeue());
3514
}
3615
}
3716

3817
public double FindMedian() {
39-
if (nums.Count % 2 == 1) {
40-
return (double)nums[nums.Count / 2];
41-
} else {
42-
if (nums.Count == 0) {
43-
return 0;
44-
} else {
45-
return (double) (nums[nums.Count / 2 - 1] + nums[nums.Count / 2]) / 2;
46-
}
47-
}
18+
return minQ.Count == maxQ.Count ? (minQ.Peek() + maxQ.Peek()) / 2.0 : minQ.Peek();
4819
}
4920
}
5021

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,29 @@
11
type MedianFinder struct {
2-
q1 hp
3-
q2 hp
2+
minq hp
3+
maxq hp
44
}
55

6-
/** initialize your data structure here. */
76
func Constructor() MedianFinder {
87
return MedianFinder{hp{}, hp{}}
98
}
109

1110
func (this *MedianFinder) AddNum(num int) {
12-
heap.Push(&this.q1, num)
13-
heap.Push(&this.q2, -heap.Pop(&this.q1).(int))
14-
if this.q2.Len()-this.q1.Len() > 1 {
15-
heap.Push(&this.q1, -heap.Pop(&this.q2).(int))
11+
minq, maxq := &this.minq, &this.maxq
12+
heap.Push(maxq, -num)
13+
heap.Push(minq, -heap.Pop(maxq).(int))
14+
if minq.Len()-maxq.Len() > 1 {
15+
heap.Push(maxq, -heap.Pop(minq).(int))
1616
}
1717
}
1818

1919
func (this *MedianFinder) FindMedian() float64 {
20-
if this.q2.Len() > this.q1.Len() {
21-
return -float64(this.q2.IntSlice[0])
20+
minq, maxq := this.minq, this.maxq
21+
if minq.Len() == maxq.Len() {
22+
return float64(minq.IntSlice[0]-maxq.IntSlice[0]) / 2
2223
}
23-
return float64(this.q1.IntSlice[0]-this.q2.IntSlice[0]) /2.0
24+
return float64(minq.IntSlice[0])
2425
}
2526

26-
/**
27-
* Your MedianFinder object will be instantiated and called as such:
28-
* obj := Constructor();
29-
* obj.AddNum(num);
30-
* param_2 := obj.FindMedian();
31-
*/
32-
3327
type hp struct{ sort.IntSlice }
3428

3529
func (h hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
@@ -39,4 +33,11 @@ func (h *hp) Pop() any {
3933
v := a[len(a)-1]
4034
h.IntSlice = a[:len(a)-1]
4135
return v
42-
}
36+
}
37+
38+
/**
39+
* Your MedianFinder object will be instantiated and called as such:
40+
* obj := Constructor();
41+
* obj.AddNum(num);
42+
* param_2 := obj.FindMedian();
43+
*/
Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
11
class MedianFinder {
2-
private PriorityQueue<Integer> q1 = new PriorityQueue<>();
3-
private PriorityQueue<Integer> q2 = new PriorityQueue<>(Collections.reverseOrder());
2+
private PriorityQueue<Integer> minQ = new PriorityQueue<>();
3+
private PriorityQueue<Integer> maxQ = new PriorityQueue<>(Collections.reverseOrder());
44

5-
/** initialize your data structure here. */
65
public MedianFinder() {
76
}
87

98
public void addNum(int num) {
10-
q1.offer(num);
11-
q2.offer(q1.poll());
12-
if (q2.size() - q1.size() > 1) {
13-
q1.offer(q2.poll());
9+
maxQ.offer(num);
10+
minQ.offer(maxQ.poll());
11+
if (minQ.size() - maxQ.size() > 1) {
12+
maxQ.offer(minQ.poll());
1413
}
1514
}
1615

1716
public double findMedian() {
18-
if (q2.size() > q1.size()) {
19-
return q2.peek();
20-
}
21-
return (q1.peek() + q2.peek()) * 1.0 / 2;
17+
return minQ.size() == maxQ.size() ? (minQ.peek() + maxQ.peek()) / 2.0 : minQ.peek();
2218
}
2319
}
2420

@@ -27,4 +23,4 @@ public double findMedian() {
2723
* MedianFinder obj = new MedianFinder();
2824
* obj.addNum(num);
2925
* double param_2 = obj.findMedian();
30-
*/
26+
*/
Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,33 @@
1-
/**
2-
* initialize your data structure here.
3-
*/
41
var MedianFinder = function () {
5-
this.val = [];
2+
this.minQ = new MinPriorityQueue();
3+
this.maxQ = new MaxPriorityQueue();
64
};
75

86
/**
97
* @param {number} num
108
* @return {void}
119
*/
1210
MedianFinder.prototype.addNum = function (num) {
13-
let left = 0;
14-
let right = this.val.length;
15-
while (left < right) {
16-
let mid = left + ~~((right - left) / 2);
17-
if (num > this.val[mid]) {
18-
left = mid + 1;
19-
} else {
20-
right = mid;
21-
}
11+
this.maxQ.enqueue(num);
12+
this.minQ.enqueue(this.maxQ.dequeue().element);
13+
if (this.minQ.size() - this.maxQ.size() > 1) {
14+
this.maxQ.enqueue(this.minQ.dequeue().element);
2215
}
23-
this.val.splice(left, 0, num);
2416
};
2517

2618
/**
2719
* @return {number}
2820
*/
2921
MedianFinder.prototype.findMedian = function () {
30-
let mid = ~~(this.val.length / 2);
31-
return this.val.length % 2 ? this.val[mid] : (this.val[mid - 1] + this.val[mid]) / 2;
22+
if (this.minQ.size() === this.maxQ.size()) {
23+
return (this.minQ.front().element + this.maxQ.front().element) / 2;
24+
}
25+
return this.minQ.front().element;
3226
};
27+
28+
/**
29+
* Your MedianFinder object will be instantiated and called as such:
30+
* var obj = new MedianFinder()
31+
* obj.addNum(num)
32+
* var param_2 = obj.findMedian()
33+
*/

‎solution/0200-0299/0295.Find Median from Data Stream/Solution.py‎

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
class MedianFinder:
2+
23
def __init__(self):
3-
"""
4-
initialize your data structure here.
5-
"""
6-
self.h1 = []
7-
self.h2 = []
4+
self.minq = []
5+
self.maxq = []
86

97
def addNum(self, num: int) -> None:
10-
heappush(self.h1, num)
11-
heappush(self.h2, -heappop(self.h1))
12-
if len(self.h2) - len(self.h1) > 1:
13-
heappush(self.h1, -heappop(self.h2))
8+
heappush(self.minq, -heappushpop(self.maxq, -num))
9+
if len(self.minq) - len(self.maxq) > 1:
10+
heappush(self.maxq, -heappop(self.minq))
1411

1512
def findMedian(self) -> float:
16-
if len(self.h2) > len(self.h1):
17-
return -self.h2[0]
18-
return (self.h1[0]-self.h2[0]) /2
13+
if len(self.minq) == len(self.maxq):
14+
return (self.minq[0] -self.maxq[0]) /2
15+
return self.minq[0]
1916

2017

2118
# Your MedianFinder object will be instantiated and called as such:
Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,35 @@
1+
use std::cmp::Reverse;
2+
use std::collections::BinaryHeap;
3+
14
struct MedianFinder {
2-
nums: Vec<i32>,
5+
minQ: BinaryHeap<Reverse<i32>>,
6+
maxQ: BinaryHeap<i32>,
37
}
48

5-
/**
6-
* `&self` means the method takes an immutable reference.
7-
* If you need a mutable reference, change it to `&mut self` instead.
8-
*/
99
impl MedianFinder {
10-
/** initialize your data structure here. */
1110
fn new() -> Self {
12-
Self { nums: Vec::new() }
11+
MedianFinder {
12+
minQ: BinaryHeap::new(),
13+
maxQ: BinaryHeap::new(),
14+
}
1315
}
1416

1517
fn add_num(&mut self, num: i32) {
16-
let mut l = 0;
17-
let mut r = self.nums.len();
18-
while l < r {
19-
let mid = (l + r) >> 1;
20-
if self.nums[mid] < num {
21-
l = mid + 1;
22-
} else {
23-
r = mid;
24-
}
18+
self.maxQ.push(num);
19+
self.minQ.push(Reverse(self.maxQ.pop().unwrap()));
20+
21+
if self.minQ.len() > self.maxQ.len() + 1 {
22+
self.maxQ.push(self.minQ.pop().unwrap().0);
2523
}
26-
self.nums.insert(l, num);
2724
}
2825

2926
fn find_median(&self) -> f64 {
30-
let n = self.nums.len();
31-
if (n & 1) == 1 {
32-
return f64::from(self.nums[n >> 1]);
27+
if self.minQ.len() == self.maxQ.len() {
28+
let min_top = self.minQ.peek().unwrap().0;
29+
let max_top = *self.maxQ.peek().unwrap();
30+
(min_top + max_top) as f64 / 2.0
31+
} else {
32+
self.minQ.peek().unwrap().0 as f64
3333
}
34-
f64::from(self.nums[n >> 1] + self.nums[(n >> 1) - 1]) / 2.0
3534
}
3635
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /