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. 五.CSS盒子模型

    所谓盒模型,就是浏览器为每个HTML元素生成的矩形盒子.即HTML页面实际上就是由一系列盒子组成.这些盒子是按照可见版式在页面上排布的.并由三个属性进行控制:position属性,display属性, ...

  2. Python类和实例

    面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可 ...

  3. ueditor 单独图片上传 转载

    <body> <script type="text/javascript"> //这个是图片上传的,网上还有附件上传的 (function($) { var ...

  4. 第八篇、封装NSURLSession网络请求框架

    主要功能介绍: 1.GET请求操作 2.POST请求操作 1.处理params参数(例如拼接成:usename="123"&password="123" ...

  5. iOS - 使用进阶

    1. 状态栏显示风火轮 //  ViewController.m //  1.状态栏显示风火轮 // //  Created by wind on 16/11/13. //  Copyright © ...

  6. ADO.NET笔记——使用Connection连接数据库,使用Command对象的ExecuteReader()方法创建DataReader对象返回多行数据

    使用Connection连接数据库,使用DataReader访问数据库,并返回多行数据. 相关步骤: 需要引入两个命名空间 using System.Data; using System.Data.S ...

  7. 开始ubuntu 14.04 的装X模式---终端模式下中文输入,听歌,上irc 开启framebuffer看电影 截图

    先上图吧 卡卡的全是在tty1 下的操作,看电影,听歌,截图 ,看图  ,上irc 等等,相当适合在小白面前装屁! 需要安装的软件: 为了能正常显示中文:安装fbterm sudo apt-get i ...

  8. 【转】CSS实现兼容性的渐变背景(gradient)效果

    一.有点俗态的开场白 要是两年前,实现“兼容性的渐变效果”这个说法估计不会被提出来的,那个时候,说起渐变背景,想到的多半是IE的渐变滤镜,其他浏览器尚未支持,但是,在对CSS3支持日趋完善的今天,实现 ...

  9. .Net平台Winform两个ComboBox控件绑定同一个数据源

    今天WINFROM编程遇到这么一个问题:是有关WINFORM中两个comboBox控件绑定同一个数据源的问题,在窗体的界面上有两个comboBox,我在Form1_Load中对他们做了数据绑定(具体代 ...

  10. java 反射的踩的一个坑

    今天工作的时候用到了一个反射.其业务简单描述为:系统启动时将需要定时调用的方法签名保存到数据库中,开启线程定时从数据库中读取对应的方法签名,通过反射生成实例后调用方法.完成一定的定时任务. 写到的方法 ...