Patching Array

Solution For Patching Array

Problem:

Given an array, arr, of size n and multiples queries, each query has three values: idx, val and inc. You must increase the array value at position idx by val and also increase all subsequent elements in the array by inc. You need to return the final array after all queries have been applied.

Example:

Input: arr = [1,2,3,4,5], queries = [[1,5,3],[4,10,2],[2,3,1]] Output: [1,8,11,14,18] Explanation:
Initially, the array is [1,2,3,4,5].
Query 1: Increase the value at index 1 by 5. The array becomes [1,7,3,4,5].
Query 2: Increase the value at index 4 by 10 and all subsequent elements by 2. The array becomes [1,7,3,4,15].
Query 3: Increase the value at index 2 by 3 and all subsequent elements by 1. The array becomes [1,7,4,5,16].
The final array is [1,8,11,14,18].

Solution:

Approach:
The question seems intimidating at first as we have a lot of queries and we are supposed to update the subsequent elements in the array too. However, if we look at the queries carefully, we can find a pattern that would enable us to come up with a solution. We can iterate through all the queries in order and for each query, we can update the idx value by the given val. After that, we increment all subsequent values in the array by the given increment using a simple for loop.

Algorithm:

  1. Initialize a variable ‘n’ to store the length of the array.
  2. Initialize a variable ‘index’ to keep track of the current index being processed.
  3. Iterate through all the queries in order, for each query:
  4. Update the idx value by the given val.
  5. Increment all subsequent values in the array by the given increment using a simple for loop.
  6. Return the final array after all queries have been applied.

Implementation:

Let’s implement the above algorithm in Python.

def patchingArray(n,queries):
arr = [0]*n # initialize the array with n zeros
index = 0 # keep track of the current index being processed
for query in queries:
idx = query[0] val = query[1] inc = query[2]

    # update the value at idx by val
    arr[idx] += val

    # increment all subsequent values by inc
    for i in range(idx+1,n):
        arr[i] += inc
return arr

The time complexity of the above algorithm is O(n*q) where n is the length of the array and q is the number of queries. However, this approach may not be the optimal solution for larger arrays or a large number of queries.

Optimized Solution:

Approach:
The above solution has a time complexity of O(n*q), which may become impractical for larger arrays or a large number of queries. We can optimize this algorithm by calculating the final values for each index in the array using a dynamic programming approach. We will iterate through the queries in order and for each query, we will update the final array according to the given values. We can use a dictionary to store the previous index that was updated. Whenever we encounter a new index, we can calculate the intermediate values and update the array accordingly.

Algorithm:

  1. Initialize a variable ‘n’ to store the length of the array.
  2. Initialize a variable ‘index’ to keep track of the current index being processed.
  3. Initialize an empty dictionary ‘prev’.
  4. Initialize the final array with n zeros.
  5. Iterate through all the queries in order, for each query:
  6. Find the previous index that was updated from the dictionary. If there is no such index, assume the previous index was -1.
  7. For the current query, update the intermediate value by adding val to all elements in the final array from the previous index+1 to the current index-1.
  8. Update the final array at the current index by adding the intermediate value to the val.
  9. If the current index is not in the dictionary, add it with the previous index value as the key and current index as the value.
  10. Return the final array.

Implementation:

Let’s implement the above algorithm in Python.

def patchingArray(n,queries):
prev = {} # store the previous index that was updated
ans = [0]*n # initialize the final array with n zeros

for q in queries:
    idx = q[0]
    val = q[1]
    inc = q[2]

    # find the previous index that was updated
    if idx-1 in prev:
        start = prev[idx-1]+1
    else:
        start = 0

    # update the intermediate value by adding val to all elements in the final array from start to idx-1
    for i in range(start,idx):
        ans[i] += val

    # update the final array at the current index by adding the intermediate value to the val
    ans[idx] += val

    # store the current index as the previous index for future queries
    prev[idx] = idx

    # update all subsequent elements by the given increment
    if idx+1<n:
        ans[idx+1] += inc

return ans

The time complexity of the above algorithm is O(n+q) where n is the length of the array and q is the number of queries. Thus, this is a much more efficient solution than the previous one.

Conclusion:

In this question, we learned how to patch an array by updating the given elements and all subsequent elements in the array. We implemented two solutions: a simple brute-force approach and an optimized dynamic programming approach. The dynamic programming approach was much more efficient as it had a lower time complexity.

Step by Step Implementation For Patching Array

class Solution {
    public int minPatches(int[] nums, int n) {
        // edge case
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        // variables
        int count = 0;
        long max = 0;
        int i = 0;
        
        // loop through the array
        while (max < n) {
            // if the current number can extend the range
            if (i < nums.length && nums[i] <= max + 1) {
                // extend the range
                max += nums[i];
                i++;
            } else {
                // add a number to extend the range
                max += max + 1;
                count++;
            }
        }
        
        return count;
    }
}
class Solution:
    def minPatches(self, nums: List[int], n: int) -> int:
        # initialize the number of patches needed as patches
        patches = 0
        # set the miss to 1 as we need to patch up to this number
        miss = 1
        # set the index to 0 as we start iterating from the beginning of the nums list
        index = 0
        # while the miss is less than or equal to n
        while miss <= n:
            # if the index is less than the length of nums and the current number in nums is less than or equal to the miss
            if index < len(nums) and nums[index] <= miss:
                # the miss is now equal to the miss plus the current number in nums
                miss += nums[index]
                # increment the index by 1
                index += 1
            # otherwise, we need to add a patch
            else:
                # the miss is now equal to the miss plus the miss
                miss += miss
                # increment patches by 1
                patches += 1
        # return the number of patches
        return patches
/**
 * @param {number[]} nums
 * @param {number} n
 * @return {number}
 */
var minPatches = function(nums, n) {
    
};
class Solution {
public:
    int minPatches(vector& nums, int n) {
        long long maxNum = 0;
        int result = 0, i = 0;
        while (maxNum < n) {
            if (i < nums.size() && nums[i] <= maxNum + 1) {
                maxNum += nums[i++];
            } else {
                maxNum += maxNum + 1;
                result++;
            }
        }
        return result;
    }
};
public class Solution {
    public int MinPatches(int[] nums, int n) {
        // we need to add patches to make the array a continuous sequence
        // that goes from 1 to n
        // we can keep track of the upper bound of the continuous sequence
        // that we have seen so far, and add patches accordingly
        long upper = 0;
        int count = 0;
        int i = 0;
        while (upper < n) {
            // if the current element can extend the upper bound
            // then we use it and move on to the next element
            if (i < nums.Length && nums[i] <= upper + 1) {
                upper += nums[i];
                i++;
            }
            // otherwise, we add a patch at upper + 1
            // and update the upper bound
            else {
                upper += upper + 1;
                count++;
            }
        }
        return count;
    }
}


Scroll to Top
[gravityforms id="5" description="false" titla="false" ajax="true"]