[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 ...
随机推荐
- (转)myeclipse工程 junit不能运行 ClassNotFoundException
博文转自:http://www.cnblogs.com/java-zone/articles/2730722.html myeclipse工程 junit不能运行 1 2 3 4 5 6 7 8 ...
- CF888E Maximum Subsequence (Meet in the middle,贪心)
题目链接 Solution Meet in the middle. 考虑到 \(2^{35}\) 枚举会超时,于是分成两半枚举(尽量平均). 然后不能 \(n^2\) 去匹配,需要用到一点贪心: 将数 ...
- (转)MSI - Enable MSI Logging
转自: http://www.cnblogs.com/atempcode/archive/2007/04/10/707917.html 安装MSI安装包的时候, 有时会遇到错误, 这时LOG文件就非常 ...
- 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---57
以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:
- Windows消息类型
WM_ Window Message 窗口消息,一般用在SendMessage,PostMessage这样的消息函数中 SM_ Static Message 静态标签消息 SS_ Static Sty ...
- CSS,HTML页面定制
/*simplememory*/ #google_ad_c1, #google_ad_c2 {display:none;} .syntaxhighlighter a, .syntaxhighlight ...
- kibana-metric
1. Visualize 新建图形 2. 选择图形类型 3. 选择索引 4. 设置metric参数 4.1 count 4.2 unique count 5. 保存图形
- log4j - 1
具体内容: 1. 如何在项目中配置log4j使得该系统可以输出web test的日志文件(自定义格式)到工程dist目录下的junitLog/WebTestLog.log目录下,输出508 ...
- 前端html第三方登录
首先推荐一下,这个博客主的文章:https://www.cnblogs.com/v-weiwang/p/5732423.html 很不错,基本靠他的博客. 我这里记一点自己调试过程中的报错等: 1,微 ...
- APIO2018练习赛伪题解
传送门:https://pcms.university.innopolis.ru/statements/org/apio/2018/practice/statements.pdf 主要就在于后面三道构 ...