All Downloads are FREE. Search and download functionalities are using the official Maven repository.

g0201_0300.s0295_find_median_from_data_stream.solution.ts Maven / Gradle / Ivy

// #Hard #Top_100_Liked_Questions #Top_Interview_Questions #Sorting #Two_Pointers #Design
// #Heap_Priority_Queue #Data_Stream #Big_O_Time_O(n*log_n)_Space_O(n)
// #2023_10_13_Time_335_ms_(99.44%)_Space_96.8_MB_(69.49%)

class Heap {
    private heap: number[]

    constructor() {
        this.heap = [0]
    }

    peek(): number | null {
        return this.heap[1] ?? null
    }

    push(val: number): void {
        this.heap.push(val)
        let i = this.heap.length - 1
        let parI = Math.floor(i / 2)
        while (i > 1 && this.heap[i] < this.heap[parI]) {
            const tmp = this.heap[i]
            this.heap[i] = this.heap[parI]
            this.heap[parI] = tmp
            i = parI
            parI = Math.floor(i / 2)
        }
    }

    pop(): number | null {
        if (this.heap.length == 1) {
            return null
        }
        if (this.heap.length == 2) {
            return this.heap.pop()
        }
        const res = this.heap[1]
        this.heap[1] = this.heap.pop()
        let i = 1
        while (2 * i < this.heap.length) {
            const leftChildIdx = 2 * i
            const rightChildIdx = 2 * i + 1
            if (
                rightChildIdx < this.heap.length &&
                this.heap[rightChildIdx] < this.heap[leftChildIdx] &&
                this.heap[i] > this.heap[rightChildIdx]
            ) {
                const tmp = this.heap[i]
                this.heap[i] = this.heap[rightChildIdx]
                this.heap[rightChildIdx] = tmp
                i = rightChildIdx
            } else if (this.heap[i] > this.heap[leftChildIdx]) {
                const tmp = this.heap[i]
                this.heap[i] = this.heap[leftChildIdx]
                this.heap[leftChildIdx] = tmp
                i = leftChildIdx
            } else {
                break
            }
        }
        return res
    }

    length(): number {
        return this.heap.length - 1
    }
}

class MedianFinder {
    large: Heap
    small: Heap

    constructor() {
        this.large = new Heap()
        this.small = new Heap()
    }

    addNum(num: number): void {
        if (this.small.length() === this.large.length()) {
            this.small.push(-num)
            this.large.push(-this.small.pop())
        } else {
            this.large.push(num)
            this.small.push(-this.large.pop())
        }
    }

    findMedian(): number {
        if (this.small.length() === this.large.length()) {
            return (this.large.peek() - this.small.peek()) / 2
        }
        return this.large.peek()
    }
}

/*
 * Your MedianFinder object will be instantiated and called as such:
 * var obj = new MedianFinder()
 * obj.addNum(num)
 * var param_2 = obj.findMedian()
 */

export { MedianFinder }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy