Minimum Operations to Make Array Equal to Target

Medium
10 days ago

You are given two positive integer arrays nums and target, of the same length.

In a single operation, you can select any subarray of nums and increment each element within that subarray by 1 or decrement each element within that subarray by 1.

Return the minimum number of operations required to make nums equal to the array target.

Example 1:

nums = [3,5,1,2], target = [4,6,2,4]

Output: 2

Explanation:

We will perform the following operations to make nums equal to target:

  • Increment nums[0..3] by 1, nums = [4,6,2,3].
  • Increment nums[3..3] by 1, nums = [4,6,2,4].

Example 2:

nums = [1,3,2], target = [2,1,4]

Output: 5

Explanation:

We will perform the following operations to make nums equal to target:

  • Increment nums[0..0] by 1, nums = [2,3,2].
  • Decrement nums[1..1] by 1, nums = [2,2,2].
  • Decrement nums[1..1] by 1, nums = [2,1,2].
  • Increment nums[2..2] by 1, nums = [2,1,3].
  • Increment nums[2..2] by 1, nums = [2,1,4].

Constraints:

  • 1 <= nums.length == target.length <= 10^5
  • 1 <= nums[i], target[i] <= 10^8
Sample Answer

Naive Approach

The most straightforward approach is to iterate through the arrays and, for each index i, if nums[i] is not equal to target[i], increment or decrement nums[i] until it matches target[i]. This approach considers each element independently and doesn't take advantage of potential subarray operations.

def min_operations_naive(nums, target):
    operations = 0
    for i in range(len(nums)):
        operations += abs(nums[i] - target[i])
    return operations

Optimal Approach

This problem can be solved more efficiently by considering the differences between adjacent elements. The key insight is that the number of operations is related to the sum of absolute differences between adjacent elements in the diff array (where diff[i] = target[i] - nums[i]). We can calculate the initial difference, and then accumulate the absolute changes in the differences between each subsequent element.

Here's a step-by-step breakdown:

  1. Calculate the difference array diff[i] = target[i] - nums[i].
  2. Initialize the number of operations with the absolute value of the first element in the diff array.
  3. Iterate through the diff array starting from the second element.
  4. For each element, add the absolute difference between the current element and the previous element to the total number of operations.
def min_operations_optimal(nums, target):
    n = len(nums)
    diff = [target[i] - nums[i] for i in range(n)]
    
    operations = abs(diff[0])
    for i in range(1, n):
        operations += abs(diff[i] - diff[i-1])
    
    return operations

Example

Let's walk through Example 1: nums = [3,5,1,2], target = [4,6,2,4]

  1. diff = [1, 1, 1, 2]
  2. operations = abs(1) = 1
  3. Loop:
    • i = 1: operations += abs(1 - 1) = 1 + 0 = 1
    • i = 2: operations += abs(1 - 1) = 1 + 0 = 1
    • i = 3: operations += abs(2 - 1) = 1 + 1 = 2
  4. Return 2

Big(O) Run-time Analysis

The optimal approach iterates through the arrays once to calculate the difference array and then iterates through the difference array once to compute the operations. Both iterations take O(n) time, where n is the length of the arrays. Therefore, the overall time complexity is O(n).

Big(O) Space Usage Analysis

The optimal approach creates a difference array of size n. Thus, the space complexity is O(n).

Edge Cases

  1. Empty arrays: If the input arrays are empty, the function should return 0.
  2. Arrays of different lengths: The problem statement specifies that the arrays have the same length, but we might want to add a check to handle cases where they don't.
  3. Large integer values: The values in nums and target can be up to 108. The difference between them could also be large. Ensure that the data type used to store the differences and operations can handle these large values to prevent overflow.

Code with Edge Case Handling

def min_operations(nums, target):
    if not nums or not target:
        return 0
    
    if len(nums) != len(target):
        raise ValueError("Arrays must have the same length")

    n = len(nums)
    diff = [target[i] - nums[i] for i in range(n)]

    operations = abs(diff[0])
    for i in range(1, n):
        operations += abs(diff[i] - diff[i-1])

    return operations