Published 2024-12-15

3264. Final Array State After K Multiplication Operations I

leetcode

Problem

You are given an array of size n, consisting of integers, and an integer K. You have to perform K multiplication operations on the array. In each operation, choose the element that can be increased the least by multiplying it by a constant factor greater than 1. After performing K such operations, your task is to find the final state of the array.

Solution Description

To implement the solution, we need to identify the smallest element in the array multiple times, as that is the element which will benefit the least from a multiplication operation. By focusing on the smallest elements, we ensure that overall growth is minimized. This requires:

  • Using a data structure that allows for efficient retrieval and updating of the smallest element, like a min-heap.
  • We will pop the smallest element from the heap, apply the multiplication, and then push it back.
  • After processing K operations, the heap will contain the modified elements which represent the final array state.

The time complexity is O(K log n) because we perform K operations and obtaining the smallest element from the heap is logarithmic in terms of the number of elements, n. The space complexity is O(n) due to storing all elements in the heap.

Example

Suppose we have an array [4, 2, 5] and K = 3, and a constant multiplication factor, say 2.

  • Initially, the smallest element is 2, which is multiplied by 2, making the array [4, 4, 5].
  • The smallest element is now 4, multiply by 2, and the array changes to [8, 4, 5].
  • Again, the smallest remains 4. Multiply by 2, resulting in [8, 8, 5].
  • Final state is [8, 8, 5] after 3 operations.

Solution

2024-12-16 Final Array State After K Multiplication Operations I - Submission Detail - LeetCode leetcode.com

Introduce the solution framework incorporating tests:

class MinHeap {
    constructor() {
        this.heap = [];
    }

    getParentIndex(i) { return Math.floor((i - 1) / 2); }
    getLeftChildIndex(i) { return 2 * i + 1; }
    getRightChildIndex(i) { return 2 * i + 2; }

    swap(i, j) {
        [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
    }

    // Insert an element as {value, index} to maintain stable priority
    insert(value, index) {
        this.heap.push({ value, index });
        let i = this.heap.length - 1;
        // Move up while the parent is greater or if tie on value, the parent's index is greater
        while (
            i !== 0 &&
            (this.heap[this.getParentIndex(i)].value > this.heap[i].value ||
            (this.heap[this.getParentIndex(i)].value === this.heap[i].value &&
             this.heap[this.getParentIndex(i)].index > this.heap[i].index))
        ) {
            this.swap(i, this.getParentIndex(i));
            i = this.getParentIndex(i);
        }
    }

    extractMin() {
        if (this.heap.length === 0) return null;
        if (this.heap.length === 1) return this.heap.pop();

        const min = this.heap[0];
        this.heap[0] = this.heap.pop();
        this.heapify(0);
        return min;
    }

    heapify(i) {
        const left = this.getLeftChildIndex(i);
        const right = this.getRightChildIndex(i);
        let smallest = i;

        if (left < this.heap.length) {
            if (
                this.heap[left].value < this.heap[smallest].value ||
                (this.heap[left].value === this.heap[smallest].value &&
                 this.heap[left].index < this.heap[smallest].index)
            ) {
                smallest = left;
            }
        }

        if (right < this.heap.length) {
            if (
                this.heap[right].value < this.heap[smallest].value ||
                (this.heap[right].value === this.heap[smallest].value &&
                 this.heap[right].index < this.heap[smallest].index)
            ) {
                smallest = right;
            }
        }

        if (smallest !== i) {
            this.swap(i, smallest);
            this.heapify(smallest);
        }
    }

    peek() {
        return this.heap[0] || null;
    }
}

/**
 * Multiplies elements of the array K times based on the described operations.
 * @param {number[]} arr - The input array of integers.
 * @param {number} k - The number of multiplication operations to perform.
 * @param {number} factor - The multiplication factor greater than 1.
 * @returns {number[]} The final state of the array after K operations.
 */
function getFinalState(arr, k, factor) {
    if (arr.length === 0) return [];

    const minHeap = new MinHeap();

    // Insert elements with their original indices
    arr.forEach((val, idx) => {
        minHeap.insert(val, idx);
    });

    // Perform k operations
    for (let i = 0; i < k; i++) {
        const minElement = minHeap.extractMin();
        const newVal = minElement.value * factor;
        minHeap.insert(newVal, minElement.index);
    }

    // Now extract all elements and place them in the correct positions
    const finalArray = new Array(arr.length);
    // Extract all elements from the heap
    const extractedElements = [];
    while (true) {
        const minElement = minHeap.extractMin();
        if (!minElement) break;
        extractedElements.push(minElement);
    }

    // Place them back according to their original indices
    for (const { value, index } of extractedElements) {
        finalArray[index] = value;
    }

    return finalArray;
}

// Test cases for the solution function
const testCases = [
    { arr: [2,1,3,5,6], k: 5, factor: 2, expected: [8,4,6,5,6] },
    { arr: [1,2], k: 3, factor: 4, expected: [16,8] },
    { arr: [5], k: 5, factor: 2, expected: [160] },
];

testCases.forEach((test, index) => {
    const result = getFinalState(test.arr, test.k, test.factor);
    console.log(`Test Case ${index + 1}: ${JSON.stringify(result) === JSON.stringify(test.expected) ? 'Passed' : 'Failed'} (Expected: ${test.expected}, Got: ${result})`);
});

References

  • Min-Heap data structure is useful when operations require minimum element extraction: Binary Heap
  • Heaps in JavaScript can be implemented using arrays with libraries like Heap.js.
© d)zharii. sitemap