Jesse and Cookies

  • + 0 comments

    My answer with Typescript.

    Firsts of all, i tried using loop and sequential search/sort to find the 2 smallest elements, it worked but not fast enough.

    function cookies(k: number, A: number[]): number {
        A.sort((a, b) => a - b);
    
        let iterations = 0;
        while (A[0] < k) {
            if (A.length < 2) return -1;
    
            const l1 = A.shift()!;
            const l2 = A.shift()!;
            const newCookie = l1 + 2 * l2;
    
            let low = 0, high = A.length;
            while (low < high) {
                const mid = Math.floor((low + high) / 2);
                if (A[mid] < newCookie) low = mid + 1;
                else high = mid;
            }
            A.splice(low, 0, newCookie);
    
            iterations++;
        }
    
        return iterations;
    }
    

    Then i tried using MinHeap and it was surprisingly fast, all tests completed instantly

    class MinHeap {
        private heap: number[] = [];
    
        insert(value: number): void {
            this.heap.push(value);
            this.heapifyUp();
        }
    
        extractMin(): number | undefined {
            if (this.heap.length === 1) return this.heap.pop();
            const min = this.heap[0];
            this.heap[0] = this.heap.pop()!;
            this.heapifyDown();
            return min;
        }
    
        peek(): number | undefined {
            return this.heap[0];
        }
    
        size(): number {
            return this.heap.length;
        }
    
        private heapifyUp(): void {
            let index = this.heap.length - 1;
            while (index > 0) {
                const parentIndex = Math.floor((index - 1) / 2);
                if (this.heap[index] >= this.heap[parentIndex]) break;
                [this.heap[index], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[index]];
                index = parentIndex;
            }
        }
    
        private heapifyDown(): void {
            let index = 0;
            while (index * 2 + 1 < this.heap.length) {
                let minChildIndex = index * 2 + 1;
                if (index * 2 + 2 < this.heap.length && this.heap[index * 2 + 2] < this.heap[minChildIndex]) {
                    minChildIndex = index * 2 + 2;
                }
                if (this.heap[index] <= this.heap[minChildIndex]) break;
                [this.heap[index], this.heap[minChildIndex]] = [this.heap[minChildIndex], this.heap[index]];
                index = minChildIndex;
            }
        }
    }
    
    function cookies(k: number, A: number[]): number {
        const heap = new MinHeap();
        A.forEach(num => heap.insert(num));
    
        let iterations = 0;
    
        while (heap.peek()! < k) {
            if (heap.size() < 2) return -1;
            const l1 = heap.extractMin()!;
            const l2 = heap.extractMin()!;
            heap.insert(l1 + 2 * l2);
            iterations++;
        }
    
        return iterations;
    }