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. 添加对WCF的调用(内网状态下)。

    在能连接到内网的电脑上,运行SvcUtil.exe工具即可. 如打开文件后闪退,则可打开cmd后,将文件拖入到cmd中,然后再加上文件的地址.

  2. Java面试题之hashmap中用什么hash算法解决碰撞的?

    查了一下源码(jdk8),记录一下吧,能记住就记一下吧! static final int hash(Object key) { int h; return (key == null) ? 0 : ( ...

  3. Installing Wine 1.5: configure: error: Cannot build a 32-bit program, you need to install 32-bit development libraries(转载)

    Installing Wine 1.5: configure: error: Cannot build a 32-bit program, you need to install 32-bit dev ...

  4. 更改Debian的console分辨率

    1.通过apt-get install hwinfo来安装 2.通过命令hwinfo --framebuffer来获取 eric@debian:~$ sudo sudo hwinfo --frameb ...

  5. 设置小于12px的字体

    .small-font{   font-size:12px;             -webkit-transform-origin-x: 0;            -webkit-transfo ...

  6. 求强连通块_Tarjan算法_C++

    好久没有写算法了,就放一个 Tarjan 上来凑凑数哈 强连通块由若干个点组成,任意点与点之间可以之间或间接到达,显然可以看作一个环 下面是伪代码 强记:dfn为时间不变,low取最小,下一个dfn有 ...

  7. MFC 实现打印机打印功能

    Visual C++6.0是开发Windows应用程序的强大工具,但是要通过它实现程序的打印功能,一直是初学者的一个难点,经常有朋友询问如何在VC中实现打印功能,他们往往感到在MFC提供的框架内实现这 ...

  8. BufferedInputStream&BufferedOutputStream

    使用字符缓冲区相关实现copy文件: public static void main(String[] args) { //创建文件对象指定要拷贝的文件路径(源文件),文件须存在,测试用例不做判断 F ...

  9. RobotFramework自动化4-批量操作案例【转载】

    本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/tag/robotframework/ 前言 有时候一个页面上有多个对象需要操作,如果一个个去定 ...

  10. ssh框架整合shiro权限

    关于整合shiro,首先在ssh整合的基础上进行组合 1.首先,要导入几个依赖(整合ssh与shiro的依赖): <properties><shiro.version>1.3. ...