[Algorithm] Median Maintenance algorithm implementation using TypeScript / JavaScript
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的更多相关文章
- [Algorithm] Maximum Contiguous Subarray algorithm implementation using TypeScript / JavaScript
Naive solution for this problem would be caluclate all the possible combinations: const numbers = [1 ...
- 一个"Median Maintenance"问题
题目要求: Download the text file here. The goal of this problem is to implement the "Median Mainten ...
- 如何在TypeScript/JavaScript项目里引入MD5校验和
摘要:MD5校验和则是其中一种数学算法,通常是使用工具对文件计算得出的一组32 个字符的十六进制字母和数字. 本文分享自华为云社区<TypeScript/JavaScript项目里如何做MD5校 ...
- 【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 ...
- Prim's Algorithm & Kruskal's algorithm
1. Problem These two algorithm are all used to find a minimum spanning tree for a weighted undirecte ...
- 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 ...
- TypeScript & JavaScript
http://www.typescriptlang.org/docs/tutorial.html handbook: Basic Types Variable Declarations Interfa ...
- 正则表达式(TypeScript, JavaScript)
课题 使用正则表达式匹配字符串 使用正则表达式 "\d{3}-(\d{4})-\d{2}" 匹配字符串 "123-4567-89" 返回匹配结果:'" ...
- [Algorithm] Radix Sort Algorithm
For example we have the array like this: [, , , , , ] First step is using Counting sort for last dig ...
随机推荐
- [ CodeVS冲杯之路 ] P1091
不充钱,你怎么AC? 题目:http://codevs.cn/problem/1091/ 大家都写的 DFS,然而我想到了一种贪心的做法,重点是可以A 普遍的贪心是每次删掉该深度子树最大的点,但是如果 ...
- C++虚函数表解析(基础篇)
原文:http://blog.csdn.net/haoel/article/details/1948051 一.简介 C++中的虚函数的作用主要是实现了多态的机制.虚函数(Virtual Funct ...
- iOS crash 崩溃问题的追踪方法
http://www.cnblogs.com/easonoutlook/archive/2012/12/27/2835884.html iOS crash 崩溃问题的追踪方法 在调试程序的时候,总是碰 ...
- UVA 10081 Tight numbers(POJ 2537)
直接看代码就OK.思路比较简单.就是注意概率要在转移过程中算出来.不能算成成立的方案书除以总方案数(POJ的这道题可以这么干.数据很水么.另外POJ要用%.5f,%.5lf 会WA.) #includ ...
- UVA 10079 Pizze Cutting
题意:N条直线最多把平面分成几个部分 ans=1+(N+1)*N/2; 直线数量 1 2 3 4 …………n把平面分成的块数 2 4 7 11 1+1 1+1+2 1+1+2+3 1+1+2+3+4 ...
- Windows录音API学习笔记--转
Windows录音API学习笔记 结构体和函数信息 结构体 WAVEINCAPS 该结构描述了一个波形音频输入设备的能力. typedef struct { WORD wMid; 用于波形 ...
- $.getJSON无法对外部变量进行赋值的问题
如下,即可将d中的值赋给外部变量 //把ajax的异步设置成同步,防止$.getJSON无法对外部变量进行赋值,必须在$.getJson前面 $.ajaxSetup({async:false}); $ ...
- Centos7部署Open-Falcon监控
参考博主:努力哥完成 一.Open-Falcon介绍 1.监控系统,可以从运营级别(基本配置即可),以及应用级别(二次开发,通过端口进行日志上报),对服务器.操作系统.中间件.应用进行全面的监控,及报 ...
- hdu 4081(次小生成树)
Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- C#中使用aria2c进行下载并显示进度条
正则表达式的生成网站: http://www.txt2re.com/index-csharp.php3 Aria2c下载地址: https://github.com/aria2/aria2/relea ...