Leetcode Find Median from Data Stream
2016-06-24 01:18
423 查看
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Examples:
Design a data structure that supports the following two operations:
void addNum(int num) - Add a integer number from the data stream to the data structure.
double findMedian() - Return the median of all elements so far.
For example:
Difficulty: Hard
Solution 1: sort a ArrayList, nlogn, TLE:
public class MedianFinder {
int med = 0, left = 0, right = 0;
List<Integer> list = new ArrayList<Integer>();
boolean isFirst = true, isEven = true;
// Adds a number into the data structure.
public void addNum(int num) {
list.add(num);
if(isFirst){
left = 0;
right = 0;
med = num + num;
isFirst = false;
isEven = false;
}
else if(isEven){
isEven = (!isEven);
left++;
Collections.sort(list);
med = list.get(left) + list.get(right);
}
else{
isEven = (!isEven);
right++;
Collections.sort(list);
med = list.get(left) + list.get(right);
}
}
// Returns the median of current data stream
public double findMedian() {
return (((double)(med)) / 2);
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();
Solution 2: Double Linked List (n), TLE:
class Node{
int val;
Node pre;
Node next;
public Node(int value){
val = value;
pre = null;
next = null;
}
}
public class MedianFinder {
Node root = null;
Node tail = null;
Node left = null;
Node right = null;
int len = 0;
// Adds a number into the data structure.
public void addNode(int num){
Node curr = new Node(num);
if(num >= tail.val){
tail.next = curr;
curr.pre = tail;
tail = curr;
if(len%2 == 1) right = right.next;
else left = left.next;
}
else if(num <= root.val){
root.pre = curr;
curr.next = root;
root = curr;
if(len%2 == 1) left = left.pre;
else right = right.pre;
}
else if(num < right.val && num > left.val){
right.pre = curr;
left.next = curr;
curr.next = right;
curr.pre = left;
right = curr; left = curr;
}
else if(num == right.val){
curr.next = right.next;
curr.pre = right;
right.next.pre = curr;
right.next = curr;
if(len%2 == 1) right = right.next;
else left = left.next;
}
else if(num == left.val){
curr.next = left;
curr.pre = left.pre;
left.pre.next = curr;
left.pre = curr;
if(len%2 == 1) left = left.pre;
else right = right.pre;
}
else{
Node temp;
if(num < left.val)
temp = root;
else
temp = right;
while(temp.val < num){
temp = temp.next;
}
curr.next = temp;
curr.pre = temp.pre;
temp.pre.next = curr;
temp.pre = curr;
if(num > right.val){
if(len%2 == 1) right = right.next;
else left = left.next;
}
else{
if(len%2 == 1) left = left.pre;
else right = right.pre;
}
}
}
public void addNum(int num) {
if(len == 0){
root = new Node(num);
tail = root;
left = root;
right = root;
len++;
}
else{
addNode(num);
len++;
}
}
// Returns the median of current data stream
public double findMedian() {
return (left.val + right.val) / 2.0;
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();
Solution 3: Priority Queue(logn):
public class MedianFinder {
Queue<Integer> large = new PriorityQueue<Integer>();
Queue<Integer> small = new PriorityQueue<Integer>();
// Adds a number into the data structure.
public void addNum(int num) {
large.add(num);
small.add(-large.poll());
if(large.size() != small.size()){
large.add(-small.poll());
}
}
// Returns the median of current data stream
public double findMedian() {
if((large.size() + small.size()) % 2 == 1){
return large.peek();
}
else{
return (large.peek() - small.peek()) / 2.0;
}
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();
Examples:
[2,3,4], the median is
3
[2,3], the median is
(2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
void addNum(int num) - Add a integer number from the data stream to the data structure.
double findMedian() - Return the median of all elements so far.
For example:
add(1) add(2) findMedian() -> 1.5 add(3) findMedian() -> 2
Difficulty: Hard
Solution 1: sort a ArrayList, nlogn, TLE:
public class MedianFinder {
int med = 0, left = 0, right = 0;
List<Integer> list = new ArrayList<Integer>();
boolean isFirst = true, isEven = true;
// Adds a number into the data structure.
public void addNum(int num) {
list.add(num);
if(isFirst){
left = 0;
right = 0;
med = num + num;
isFirst = false;
isEven = false;
}
else if(isEven){
isEven = (!isEven);
left++;
Collections.sort(list);
med = list.get(left) + list.get(right);
}
else{
isEven = (!isEven);
right++;
Collections.sort(list);
med = list.get(left) + list.get(right);
}
}
// Returns the median of current data stream
public double findMedian() {
return (((double)(med)) / 2);
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();
Solution 2: Double Linked List (n), TLE:
class Node{
int val;
Node pre;
Node next;
public Node(int value){
val = value;
pre = null;
next = null;
}
}
public class MedianFinder {
Node root = null;
Node tail = null;
Node left = null;
Node right = null;
int len = 0;
// Adds a number into the data structure.
public void addNode(int num){
Node curr = new Node(num);
if(num >= tail.val){
tail.next = curr;
curr.pre = tail;
tail = curr;
if(len%2 == 1) right = right.next;
else left = left.next;
}
else if(num <= root.val){
root.pre = curr;
curr.next = root;
root = curr;
if(len%2 == 1) left = left.pre;
else right = right.pre;
}
else if(num < right.val && num > left.val){
right.pre = curr;
left.next = curr;
curr.next = right;
curr.pre = left;
right = curr; left = curr;
}
else if(num == right.val){
curr.next = right.next;
curr.pre = right;
right.next.pre = curr;
right.next = curr;
if(len%2 == 1) right = right.next;
else left = left.next;
}
else if(num == left.val){
curr.next = left;
curr.pre = left.pre;
left.pre.next = curr;
left.pre = curr;
if(len%2 == 1) left = left.pre;
else right = right.pre;
}
else{
Node temp;
if(num < left.val)
temp = root;
else
temp = right;
while(temp.val < num){
temp = temp.next;
}
curr.next = temp;
curr.pre = temp.pre;
temp.pre.next = curr;
temp.pre = curr;
if(num > right.val){
if(len%2 == 1) right = right.next;
else left = left.next;
}
else{
if(len%2 == 1) left = left.pre;
else right = right.pre;
}
}
}
public void addNum(int num) {
if(len == 0){
root = new Node(num);
tail = root;
left = root;
right = root;
len++;
}
else{
addNode(num);
len++;
}
}
// Returns the median of current data stream
public double findMedian() {
return (left.val + right.val) / 2.0;
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();
Solution 3: Priority Queue(logn):
public class MedianFinder {
Queue<Integer> large = new PriorityQueue<Integer>();
Queue<Integer> small = new PriorityQueue<Integer>();
// Adds a number into the data structure.
public void addNum(int num) {
large.add(num);
small.add(-large.poll());
if(large.size() != small.size()){
large.add(-small.poll());
}
}
// Returns the median of current data stream
public double findMedian() {
if((large.size() + small.size()) % 2 == 1){
return large.peek();
}
else{
return (large.peek() - small.peek()) / 2.0;
}
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();
相关文章推荐
- 获取当前主题设置的属性
- 趣味程序设计_爱因斯坦的数学题(中剩)
- 160623dyld: Library not loaded:
- 开发错误记录11:git报错 fatal:open /dev/null or dup failed: No such file or directory
- 问题 G: 整数连接
- 《Java数据结构与算法》笔记-CH5-链表-1单链表
- Mysql引擎介绍
- Mysql优势和特点
- H5、React Native、Native应用对比分析
- 新概念英语
- literature文学评析
- 3D 电影欣赏
- 有权并查集,Poj(1988)
- 电影评析
- Java之JSP和Servlet基础知识。
- 家庭网络方案分享
- 作者:唐欢----感悟和经验
- [!] Pods written in Swift can only be integrated as frameworks; add `use_frameworks!` to your Podfil
- 个人总结
- Struts2系列:(10)struts.xml和struts.properties详解