Skip to content

feat: add solutions to lc problem: No.0295 #3166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
374 changes: 220 additions & 154 deletions solution/0200-0299/0295.Find Median from Data Stream/README.md

Large diffs are not rendered by default.

372 changes: 224 additions & 148 deletions solution/0200-0299/0295.Find Median from Data Stream/README_EN.md

Large diffs are not rendered by default.

25 changes: 11 additions & 14 deletions solution/0200-0299/0295.Find Median from Data Stream/Solution.cpp
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() {
}

void addNum(int num) {
q1.push(num);
q2.push(q1.top());
q1.pop();
if (q2.size() - q1.size() > 1) {
q1.push(q2.top());
q2.pop();
maxQ.push(num);
minQ.push(maxQ.top());
maxQ.pop();

if (minQ.size() > maxQ.size() + 1) {
maxQ.push(minQ.top());
minQ.pop();
}
}

double findMedian() {
if (q2.size() > q1.size()) {
return q2.top();
}
return (double) (q1.top() + q2.top()) / 2;
return minQ.size() == maxQ.size() ? (minQ.top() + maxQ.top()) / 2.0 : minQ.top();
}

private:
priority_queue<int, vector<int>, greater<int>> q1;
priority_queue<int> q2;
priority_queue<int> maxQ;
priority_queue<int, vector<int>, greater<int>> minQ;
};

/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/
*/
43 changes: 7 additions & 36 deletions solution/0200-0299/0295.Find Median from Data Stream/Solution.cs
Original file line number Diff line number Diff line change
@@ -1,50 +1,21 @@
public class MedianFinder {
private List<int> nums;
private int curIndex;
private PriorityQueue<int, int> minQ = new PriorityQueue<int, int>();
private PriorityQueue<int, int> maxQ = new PriorityQueue<int, int>(Comparer<int>.Create((a, b) => b.CompareTo(a)));

/** initialize your data structure here. */
public MedianFinder() {
nums = new List<int>();
}

private int FindIndex(int val) {
int left = 0;
int right = nums.Count - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (val > nums[mid]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}

public void AddNum(int num) {
if (nums.Count == 0) {
nums.Add(num);
curIndex = 0;
} else {
curIndex = FindIndex(num);
if (curIndex == nums.Count) {
nums.Add(num);
} else {
nums.Insert(curIndex, num);
}
maxQ.Enqueue(num, num);
minQ.Enqueue(maxQ.Peek(), maxQ.Dequeue());
if (minQ.Count > maxQ.Count + 1) {
maxQ.Enqueue(minQ.Peek(), minQ.Dequeue());
}
}

public double FindMedian() {
if (nums.Count % 2 == 1) {
return (double)nums[nums.Count / 2];
} else {
if (nums.Count == 0) {
return 0;
} else {
return (double) (nums[nums.Count / 2 - 1] + nums[nums.Count / 2]) / 2;
}
}
return minQ.Count == maxQ.Count ? (minQ.Peek() + maxQ.Peek()) / 2.0 : minQ.Peek();
}
}

Expand Down
37 changes: 19 additions & 18 deletions solution/0200-0299/0295.Find Median from Data Stream/Solution.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
type MedianFinder struct {
q1 hp
q2 hp
minq hp
maxq hp
}

/** initialize your data structure here. */
func Constructor() MedianFinder {
return MedianFinder{hp{}, hp{}}
}

func (this *MedianFinder) AddNum(num int) {
heap.Push(&this.q1, num)
heap.Push(&this.q2, -heap.Pop(&this.q1).(int))
if this.q2.Len()-this.q1.Len() > 1 {
heap.Push(&this.q1, -heap.Pop(&this.q2).(int))
minq, maxq := &this.minq, &this.maxq
heap.Push(maxq, -num)
heap.Push(minq, -heap.Pop(maxq).(int))
if minq.Len()-maxq.Len() > 1 {
heap.Push(maxq, -heap.Pop(minq).(int))
}
}

func (this *MedianFinder) FindMedian() float64 {
if this.q2.Len() > this.q1.Len() {
return -float64(this.q2.IntSlice[0])
minq, maxq := this.minq, this.maxq
if minq.Len() == maxq.Len() {
return float64(minq.IntSlice[0]-maxq.IntSlice[0]) / 2
}
return float64(this.q1.IntSlice[0]-this.q2.IntSlice[0]) / 2.0
return float64(minq.IntSlice[0])
}

/**
* Your MedianFinder object will be instantiated and called as such:
* obj := Constructor();
* obj.AddNum(num);
* param_2 := obj.FindMedian();
*/

type hp struct{ sort.IntSlice }

func (h hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
Expand All @@ -39,4 +33,11 @@ func (h *hp) Pop() any {
v := a[len(a)-1]
h.IntSlice = a[:len(a)-1]
return v
}
}

/**
* Your MedianFinder object will be instantiated and called as such:
* obj := Constructor();
* obj.AddNum(num);
* param_2 := obj.FindMedian();
*/
20 changes: 8 additions & 12 deletions solution/0200-0299/0295.Find Median from Data Stream/Solution.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
class MedianFinder {
private PriorityQueue<Integer> q1 = new PriorityQueue<>();
private PriorityQueue<Integer> q2 = new PriorityQueue<>(Collections.reverseOrder());
private PriorityQueue<Integer> minQ = new PriorityQueue<>();
private PriorityQueue<Integer> maxQ = new PriorityQueue<>(Collections.reverseOrder());

/** initialize your data structure here. */
public MedianFinder() {
}

public void addNum(int num) {
q1.offer(num);
q2.offer(q1.poll());
if (q2.size() - q1.size() > 1) {
q1.offer(q2.poll());
maxQ.offer(num);
minQ.offer(maxQ.poll());
if (minQ.size() - maxQ.size() > 1) {
maxQ.offer(minQ.poll());
}
}

public double findMedian() {
if (q2.size() > q1.size()) {
return q2.peek();
}
return (q1.peek() + q2.peek()) * 1.0 / 2;
return minQ.size() == maxQ.size() ? (minQ.peek() + maxQ.peek()) / 2.0 : minQ.peek();
}
}

Expand All @@ -27,4 +23,4 @@ public double findMedian() {
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
*/
33 changes: 17 additions & 16 deletions solution/0200-0299/0295.Find Median from Data Stream/Solution.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
/**
* initialize your data structure here.
*/
var MedianFinder = function () {
this.val = [];
this.minQ = new MinPriorityQueue();
this.maxQ = new MaxPriorityQueue();
};

/**
* @param {number} num
* @return {void}
*/
MedianFinder.prototype.addNum = function (num) {
let left = 0;
let right = this.val.length;
while (left < right) {
let mid = left + ~~((right - left) / 2);
if (num > this.val[mid]) {
left = mid + 1;
} else {
right = mid;
}
this.maxQ.enqueue(num);
this.minQ.enqueue(this.maxQ.dequeue().element);
if (this.minQ.size() - this.maxQ.size() > 1) {
this.maxQ.enqueue(this.minQ.dequeue().element);
}
this.val.splice(left, 0, num);
};

/**
* @return {number}
*/
MedianFinder.prototype.findMedian = function () {
let mid = ~~(this.val.length / 2);
return this.val.length % 2 ? this.val[mid] : (this.val[mid - 1] + this.val[mid]) / 2;
if (this.minQ.size() === this.maxQ.size()) {
return (this.minQ.front().element + this.maxQ.front().element) / 2;
}
return this.minQ.front().element;
};

/**
* Your MedianFinder object will be instantiated and called as such:
* var obj = new MedianFinder()
* obj.addNum(num)
* var param_2 = obj.findMedian()
*/
21 changes: 9 additions & 12 deletions solution/0200-0299/0295.Find Median from Data Stream/Solution.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
class MedianFinder:

def __init__(self):
"""
initialize your data structure here.
"""
self.h1 = []
self.h2 = []
self.minq = []
self.maxq = []

def addNum(self, num: int) -> None:
heappush(self.h1, num)
heappush(self.h2, -heappop(self.h1))
if len(self.h2) - len(self.h1) > 1:
heappush(self.h1, -heappop(self.h2))
heappush(self.minq, -heappushpop(self.maxq, -num))
if len(self.minq) - len(self.maxq) > 1:
heappush(self.maxq, -heappop(self.minq))

def findMedian(self) -> float:
if len(self.h2) > len(self.h1):
return -self.h2[0]
return (self.h1[0] - self.h2[0]) / 2
if len(self.minq) == len(self.maxq):
return (self.minq[0] - self.maxq[0]) / 2
return self.minq[0]


# Your MedianFinder object will be instantiated and called as such:
Expand Down
41 changes: 20 additions & 21 deletions solution/0200-0299/0295.Find Median from Data Stream/Solution.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
use std::cmp::Reverse;
use std::collections::BinaryHeap;

struct MedianFinder {
nums: Vec<i32>,
minQ: BinaryHeap<Reverse<i32>>,
maxQ: BinaryHeap<i32>,
}

/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl MedianFinder {
/** initialize your data structure here. */
fn new() -> Self {
Self { nums: Vec::new() }
MedianFinder {
minQ: BinaryHeap::new(),
maxQ: BinaryHeap::new(),
}
}

fn add_num(&mut self, num: i32) {
let mut l = 0;
let mut r = self.nums.len();
while l < r {
let mid = (l + r) >> 1;
if self.nums[mid] < num {
l = mid + 1;
} else {
r = mid;
}
self.maxQ.push(num);
self.minQ.push(Reverse(self.maxQ.pop().unwrap()));

if self.minQ.len() > self.maxQ.len() + 1 {
self.maxQ.push(self.minQ.pop().unwrap().0);
}
self.nums.insert(l, num);
}

fn find_median(&self) -> f64 {
let n = self.nums.len();
if (n & 1) == 1 {
return f64::from(self.nums[n >> 1]);
if self.minQ.len() == self.maxQ.len() {
let min_top = self.minQ.peek().unwrap().0;
let max_top = *self.maxQ.peek().unwrap();
(min_top + max_top) as f64 / 2.0
} else {
self.minQ.peek().unwrap().0 as f64
}
f64::from(self.nums[n >> 1] + self.nums[(n >> 1) - 1]) / 2.0
}
}
Loading
Loading