The median maintenance problem is a common programming challenge presented in software engineering job interviews.

In this lesson we cover an example of how this problem might be presented and what your chain of thought should be to tackle this problem efficiently.

Lets first refresh what is a median

  • The median is the middle element in the sorted list
  • Given a list of numbers
`
The median is the middle element in the sorted list. Given
13, 23, 11, 16, 15, 10, 26 Sort them
10, 11, 13, 15, 16, 23, 26

Median If we have an even number of elements we average E.g.
10, 11, 13, 15, 16, 23, 26, 32
\ /
15.5

They way we solve the problem is by using two heaps (Low & High) to divide the array into tow parts.

Low                 |                      High

Max Heap          |                    Min Heap

Low part is a max heap, high part is a min heap.

`
(n/2 ± 1) smallest items in a low MaxHeap (n/2 ± 1) biggest items in a high MinHeap peek => n/2th smallest peek => n/2th smallest
\ /
MEDIAN!
`

If low part size is equals to high part size, then we get avg value, otherwise, we get from larger size heap.

function MedianMaintaince() {
let lowMaxHeap = new Heap((b, a) => a - b);
let highMinHeap = new Heap((a, b) => a - b); return {
add(value) {
// For the first element, we add to lowMaxHeap by default
if (lowMaxHeap.size() === 0 || value < lowMaxHeap.peek()) {
lowMaxHeap.add(value);
} else {
highMinHeap.add(value);
} /**
* Reblance:
*
* If low.size = 2; high.size = 4, then we move the root of high to the low part
* so that low.size = 3, high.size = 3
*/
let smallerHeap =
lowMaxHeap.size() > highMinHeap.size() ? highMinHeap : lowMaxHeap;
let biggerHeap = smallerHeap === lowMaxHeap ? highMinHeap : lowMaxHeap;
if (biggerHeap.size() - smallerHeap.size() > 1) {
smallerHeap.add(biggerHeap.extractRoot());
} /**
* If low.szie === high.size, extract root for both and calculate the average value
*/
if (lowMaxHeap.size() === highMinHeap.size()) {
return (lowMaxHeap.peek() + highMinHeap.peek()) / 2;
} else {
// get peak value from the bigger size of heap
return lowMaxHeap.size() > highMinHeap.size()
? lowMaxHeap.peek()
: highMinHeap.peek();
}
}
};
} const mm = new MedianMaintaince();
console.log(mm.add(4)); //
console.log(mm.add(2)); //
console.log(mm.add(5)); //
console.log(mm.add(3)); // 3.5

We have heap data structure:

function printArray(ary) {
console.log(JSON.stringify(ary, null, 2));
} function Heap(cmpFn = () => {}) {
let data = [];
return {
data,
// 2n+1
leftInx(index) {
return 2 * index + 1;
},
//2n + 2
rightInx(index) {
return 2 * index + 2;
},
// left: (n - 1) / 2, left index is always odd number
// right: (n - 2) / 2, right index is always even number
parentInx(index) {
return index % 2 === 0 ? (index - 2) / 2 : (index - 1) / 2;
},
add(val) {
this.data.push(val);
this.siftUp(this.data.length - 1);
},
extractRoot() {
if (this.data.length > 0) {
const root = this.data[0];
const last = this.data.pop();
if (this.data.length > 0) {
// move last element to the root
this.data[0] = last;
// move last elemment from top to bottom
this.siftDown(0);
} return root;
}
},
siftUp(index) {
// find parent index
let parentInx = this.parentInx(index);
// compare
while (index > 0 && cmpFn(this.data[index], this.data[parentInx]) < 0) {
//swap parent and current node value
[this.data[index], this.data[parentInx]] = [
this.data[parentInx],
this.data[index]
];
//swap index
index = parentInx;
//move to next parent
parentInx = this.parentInx(index);
}
},
siftDown(index) {
const minIndex = (leftInx, rightInx) => {
if (cmpFn(this.data[leftInx], this.data[rightInx]) <= 0) {
return leftInx;
} else {
return rightInx;
}
};
let min = minIndex(this.leftInx(index), this.rightInx(index));
while (min >= 0 && cmpFn(this.data[index], this.data[min]) > 0) {
[this.data[index], this.data[min]] = [this.data[min], this.data[index]];
index = min;
min = minIndex(this.leftInx(index), this.rightInx(index));
}
},
peek() {
return this.data[0];
},
print() {
printArray(this.data);
},
size() {
return this.data.length;
}
};
}

  

[Algorithm] Median Maintenance algorithm implementation using TypeScript / JavaScript的更多相关文章

  1. [Algorithm] Maximum Contiguous Subarray algorithm implementation using TypeScript / JavaScript

    Naive solution for this problem would be caluclate all the possible combinations: const numbers = [1 ...

  2. 一个"Median Maintenance"问题

    题目要求: Download the text file here. The goal of this problem is to implement the "Median Mainten ...

  3. 如何在TypeScript/JavaScript项目里引入MD5校验和

    摘要:MD5校验和则是其中一种数学算法,通常是使用工具对文件计算得出的一组32 个字符的十六进制字母和数字. 本文分享自华为云社区<TypeScript/JavaScript项目里如何做MD5校 ...

  4. 【Java】-NO.13.Algorithm.1.Java Algorithm.1.001-【Java 常用算法手册 】-

    1.0.0 Summary Tittle:[Java]-NO.13.Algorithm.1.Java Algorithm.1.001-[Java 常用算法手册 ]- Style:Java Series ...

  5. Prim's Algorithm & Kruskal's algorithm

    1. Problem These two algorithm are all used to find a minimum spanning tree for a weighted undirecte ...

  6. Method for finding shortest path to destination in traffic network using Dijkstra algorithm or Floyd-warshall algorithm

    A method is presented for finding a shortest path from a starting place to a destination place in a ...

  7. TypeScript & JavaScript

    http://www.typescriptlang.org/docs/tutorial.html handbook: Basic Types Variable Declarations Interfa ...

  8. 正则表达式(TypeScript, JavaScript)

    课题 使用正则表达式匹配字符串 使用正则表达式 "\d{3}-(\d{4})-\d{2}" 匹配字符串 "123-4567-89" 返回匹配结果:'" ...

  9. [Algorithm] Radix Sort Algorithm

    For example we have the array like this: [, , , , , ] First step is using Counting sort for last dig ...

随机推荐

  1. 如何用cookie保存用户的登录的密码和用户名

    思路:绘制一个简单的登录界面的Servlet并要在此页面中读取保存密码和用户名的cookie--->在登录处理界面的servlet中把用户名和密码保存到cookie中 //登录界面的Servle ...

  2. Python学习笔记(Django篇)——2、创建第一个django应用

    在helloworld工程的基础上,我们准备创建第一个基于web的django应用,把这个应用名字命名为demo   首先,是如何创建这个应用包,当然第一选择我们可以进入到cmd中,执行如下命令 py ...

  3. Create Windows Server 2008 cluster from the command line

    How to create a Windows Server 2008 cluster from the command line? Creating a cluster in Server 2008 ...

  4. 使用keepalived监控tomcat 达到双机热备

    通常说的双机热备是指两台机器都在运行,但并不是两台机器都同时在提供服务. 当提供服务的一台出现故障的时候,另外一台会马上自动接管并且提供服务,而且切换的时间非常短.下面来以keepalived结合to ...

  5. mysql5.6免安装配置(菜鸟版)

    mysql5.6免安装配置 MySQL5.6.13安装步骤(Windows7 32位) 1. 下载MySQL Community Server 5.6.13 2. 解压MySQL压缩包 将以下载的My ...

  6. html模板引擎jade的使用

    jade语法: #{xxx} //嵌入数据 p= xxx //嵌入数据 p #{xx} //嵌入数据 标签 html // 翻译为<html></html> div#test ...

  7. Opengl场景中加光照包含几个步骤

    http://zuoye.baidu.com/question/44e2a82d7ad5c0e1d33ddb9a40e0bf86.html  Opengl场景中加光照包含几个步骤,各个步骤实现用的函数 ...

  8. xCode中去除“Implicit declaration of function 'sysctl' is invalid in C99” 警告

    http://blog.csdn.net/dreambegin/article/details/8609121 一般出现该问题是因为通过C调用了unix/linux 底层接口,所以需要调整c语言的编译 ...

  9. VIM使用技巧1

    .命令是vim中很重要的一个命令,用法如下: 加入有一个文件vimtest.txt,内容如下: 1 Line one  2 Line two                               ...

  10. Linux中断(interrupt)子系统之五:软件中断(softIRQ)【转】

    转自:http://blog.csdn.net/droidphone/article/details/7518428 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 软件中 ...