Numbers keep coming, return the median of numbers at every time a new number added.

Example

For numbers coming list: [1, 2, 3, 4, 5], return [1, 1, 2, 2, 3]

For numbers coming list: [4, 5, 1, 3, 2, 6, 0], return [4, 4, 4, 3, 3, 3, 3]

For numbers coming list: [2, 20, 100], return [2, 2, 20]

Challenge

O(nlogn) time

Clarification

What's the definition of Median?

  • Median is the number that in the middle of a sorted array. If there are n numbers in a sorted array A, the median is A[(n-1)/2].
  • For example, if A=[1,2,3], median is 2. If A=[1,19], median is 1

Analysis:

We maintain a max heap and a min heap. At any index i, the max heap stores the elements small or equal than the current median and the min heap stores the elements that are larger than the current median. Because in the problem, we select the median as at the position (n-1)/2, so we should always keep the size of max heap equal or one larger than the min heap. At odd index, we try to rebalance the size of max heap and min heap, while at even index, we try to make the size of max heap one larger than that of the min heap. By doing this, at each position, after inserting A[i] into the heaps, the root value of the max heap is the median.

NOTE: if we select (n-1)/2+1 as median, we can then keep the min heap equal or one larger than the max heap, the root value of the min heap is the median.

Solution:

I implement a Heap class with only insert and popHeapRoot functions.

 class Heap{
private int[] nodes;
private int size;
private boolean isMaxHeap; public Heap(int capa, boolean isMax){
nodes = new int[capa];
size = 0;
isMaxHeap = isMax;
} public boolean isEmpty(){
if (size==0) return true;
else return false;
} public int getHeapRootValue(){
//should throw exception when size==0;
return nodes[0];
} private void swap(int x, int y){
int temp = nodes[x];
nodes[x] = nodes[y];
nodes[y] = temp;
} public boolean insert(int val){
if (size==nodes.length) return false;
size++;
nodes[size-1]=val;
//check its father iteratively.
int cur = size-1;
int father = (cur-1)/2;
while (father>=0 && ((isMaxHeap && nodes[cur]>nodes[father]) || (!isMaxHeap && nodes[cur]<nodes[father]))){
swap(cur,father);
cur = father;
father = (cur-1)/2;
}
return true;
} private void shiftDown(int ind){
int left = (ind+1)*2-1;
int right = (ind+1)*2;
while (left<size || right<size){
if (isMaxHeap){
int leftVal = (left<size) ? nodes[left] : Integer.MIN_VALUE;
int rightVal = (right<size) ? nodes[right] : Integer.MIN_VALUE;
int next = (leftVal>=rightVal) ? left : right;
if (nodes[ind]>nodes[next]) break;
else {
swap(ind,next);
ind = next;
left = (ind+1)*2-1;
right = (ind+1)*2;
}
} else {
int leftVal = (left<size) ? nodes[left] : Integer.MAX_VALUE;
int rightVal = (right<size) ? nodes[right] : Integer.MAX_VALUE;
int next = (leftVal<=rightVal) ? left : right;
if (nodes[ind]<nodes[next]) break;
else {
swap(ind,next);
ind = next;
left = (ind+1)*2-1;
right = (ind+1)*2;
}
}
}
} public int popHeapRoot(){
//should throw exception, when heap is empty. int rootVal = nodes[0];
swap(0,size-1);
size--;
if (size>0) shiftDown(0);
return rootVal;
}
} public class Solution {
/**
* @param nums: A list of integers.
* @return: the median of numbers
*/
public int[] medianII(int[] nums) {
int[] res = new int[nums.length];
Heap maxHeap = new Heap(nums.length,true);
Heap minHeap = new Heap(nums.length,false);
maxHeap.insert(nums[0]);
res[0] = nums[0];
for (int i=1;i<nums.length;i++)
if (i %2 == 1) { //i is odd index.
int median = maxHeap.getHeapRootValue();
if (nums[i]<median){
maxHeap.popHeapRoot();
minHeap.insert(median);
maxHeap.insert(nums[i]);
res[i] = maxHeap.getHeapRootValue();
} else {
res[i] = median;
minHeap.insert(nums[i]);
}
} else { //i is even index.
int median = maxHeap.getHeapRootValue();
if (nums[i]<median){
maxHeap.insert(nums[i]);
} else {
minHeap.insert(nums[i]);
int val = minHeap.popHeapRoot();
maxHeap.insert(val);
}
res[i] = maxHeap.getHeapRootValue();
} return res;
}
}

LintCode-Median II的更多相关文章

  1. [LintCode] Median of Two Sorted Arrays 两个有序数组的中位数

    There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...

  2. Lintcode: Median

    Given a unsorted array with integers, find the median of it. A median is the middle number of the ar ...

  3. [LintCode] Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  4. LintCode: Median of two Sorted Arrays

    求第k个值 1.归并排序 归并到第k个值为止 时间复杂度:O(k) class Solution { public: // merge-sort to find K-th value double h ...

  5. [算法专题] 深度优先搜索&回溯剪枝

    1. Palindrome Partitioning https://leetcode.com/problems/palindrome-partitioning/ Given a string s, ...

  6. lintcode 最长上升连续子序列 II(二维最长上升连续序列)

    题目链接:http://www.lintcode.com/zh-cn/problem/longest-increasing-continuous-subsequence-ii/ 最长上升连续子序列 I ...

  7. Lintcode: Sort Colors II 解题报告

    Sort Colors II 原题链接: http://lintcode.com/zh-cn/problem/sort-colors-ii/# Given an array of n objects ...

  8. Lintcode: Majority Number II 解题报告

    Majority Number II 原题链接: http://lintcode.com/en/problem/majority-number-ii/# Given an array of integ ...

  9. leetcode 293.Flip Game(lintcode 914) 、294.Flip Game II(lintcode 913)

    914. Flip Game https://www.cnblogs.com/grandyang/p/5224896.html 从前到后遍历,遇到连续两个'+',就将两个加号变成'-'组成新的字符串加 ...

  10. Lintcode 150.买卖股票的最佳时机 II

    ------------------------------------------------------------ 卧槽竟然连题意都没看懂,百度了才明白题目在说啥....我好方啊....o(╯□ ...

随机推荐

  1. 一分钟加入google站内搜索代码

    一分钟加入google站内搜索代码| 一分钟加入google站内搜索代码|只有7行最精简.网上有很多 google 站内搜索代码,但是出于某些目的,很多都加入了多余的代码,从seo的角度来讲,是很不优 ...

  2. DevExpress使用之ChartControl控件绘制图表(多坐标折线图、柱状图、饼状图)

    最近因为公司项目需要用到WinForm的DecExpress控件,在这里把一些使用方法总结一下. DevExpress中有一个专门用来绘制图表的插件ChartControl,可以绘制折线图.饼状图.柱 ...

  3. android app性能优化大汇总(内存性能优化)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...

  4. JavaScript之返回顶部

    为了弄这个Hexo,今天又是坐在电脑面前待了一天( ⊙ o ⊙ ),老是出问题,在百度上也试验了很多方法,还是没弄好,诶...身心疲惫甚是乏累啊~~~ 算了,这个Hexo先不弄,还是安分点吧,在Hex ...

  5. @@ROWCOUNT (Transact-SQL)

    @@ROWCOUNT (Transact-SQL) 返回受上一语句影响的行数.如果行数大于 20 亿,请使用 ROWCOUNT_BIG. Transact-SQL 语法约定 语法 @@ROWCOUNT ...

  6. jquery页面滚动,菜单固定到顶部

    // 菜单固定 $(function(){ //获取要定位元素距离浏览器顶部的距离 var navH = $("#topp").offset().top; //滚动条事件 $(wi ...

  7. Java获取操作系统信息

    今天在看jdk的demo时候发现java获取系统操作系统的一些信息,例如内存使用情况,于是自己也想研究研究! 百度一番,发现有2种方法! 1.sun自带的API 2.第三方jar(Sigar)   先 ...

  8. setbuf

    setbuf是linux中的C函数,主要用于打开和关闭缓冲机制. setbuf函数具有打开和关闭缓冲机制.为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中) ...

  9. 阿里巴巴2013年实习生笔试题A

    一.单项选择题 1.下列说法不正确的是:(B) A.SATA硬盘的速度速度大约为500Mbps/s B.读取18XDVD光盘数据的速度为1Gbps C.前兆以太网的数据读取速度为1Gpbs D.读取D ...

  10. 向CodeBlocks的Project中添加calss文件时,出现No such file or directory错误的解决方案

    我们在CodeBlocks中编写程序时,一般要建立工程.现在建立工程first,然后建立类文件Person,并将其添加到first中, int main() { Person p; p.display ...