3229. Minimum Operations to Make Array Equal to Target
Problem Description
You are given two positive integer arrays nums
and target
, both of the same length. The goal is to transform the nums
array into the target
array using the least number of operations. An operation consists of choosing any subarray within nums
and either incrementing or decrementing each element in that subarray by 1. Your task is to determine the minimum number of operations required to achieve this transformation.
Intuition
To solve this problem, let's first consider the difference between the corresponding elements of the arrays nums
and target
. We can define a difference array where each element is the difference between the elements at the same position in the two arrays. To transform nums
into target
, the differences between the arrays must be neutralized.
The key observation is that if consecutive elements in the difference array have the same sign (both positive or both negative), these differences can be adjusted together by selecting a subarray, thus incrementing or decrementing them collectively. For an interval of differences where the signs are consistent, we should focus on adjusting the difference at the beginning. The absolute value of the first difference in such an interval should be included in the result as it denotes how much adjustment needs to be made initially. For subsequent differences, if the new difference is larger in absolute value than the previous one, the excess needs further adjustments, so the difference of the absolute values is added to the result.
This method efficiently considers the change needed for each transition between intervals of differences. Our approach iterates through the differences, updating a cumulative count of required operations to minimize the adjustments to transform nums
into target
.
Learn more about Stack, Greedy, Dynamic Programming and Monotonic Stack patterns.
Solution Approach
The solution to this problem uses a straightforward iterative approach to determine the minimum operations required to transform the nums
array into the target
array. Here's how we implement this:
-
Calculate Initial Difference:
- Start by measuring the initial difference between the first elements of
nums
andtarget
. Let's call this the initial cost,f
. Calculate it asf = abs(target[0] - nums[0])
.
- Start by measuring the initial difference between the first elements of
-
Iterate through the Arrays:
- For each subsequent element in the arrays, compute the difference
x
between the current elements oftarget
andnums
, andy
as the difference of their previous elements.
- For each subsequent element in the arrays, compute the difference
-
Adjust Operations Based on Change in Difference:
- If the differences
x
andy
share the same sign, meaning they contribute in the same direction, we compute the additional required adjustment asd = abs(x) - abs(y)
. - If this calculated
d
is positive, we add it tof
, as this indicates an increase in the absolute difference that needs to be adjusted. - If the signs of the differences
x
andy
do not match, it means the trend has changed, necessitating the adjustment of the entire current differenceabs(x)
to the operation countf
.
- If the differences
-
Return Total Operations:
- Once the iteration completes,
f
holds the minimum number of operations required to makenums
equal totarget
.
- Once the iteration completes,
This algorithm efficiently computes the necessary operations by looking at the change points in the sequence of differences, leveraging the fact that adjustments can be made collectively when differences align in their directional change. The process has a linear complexity of O(n)
due to its single traversal of the array, and it operates in constant space O(1)
, making it optimal for handling large arrays.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through an example to illustrate the solution approach. Suppose we have the following arrays:
nums = [3, 1, 2]
target = [1, 3, 2]
Our task is to transform nums
into target
with minimum operations. Here's how the algorithm works:
-
Calculate Initial Difference:
- Start by looking at the first elements of both arrays:
nums[0] = 3
andtarget[0] = 1
. - Calculate the absolute difference:
f = abs(target[0] - nums[0]) = abs(1 - 3) = 2
. - This means we need 2 operations initially to transform the first element of
nums
to matchtarget
.
- Start by looking at the first elements of both arrays:
-
Iterate through the Arrays:
- Move to the next pair of elements:
nums[1] = 1
,target[1] = 3
. - Calculate the current difference
x = target[1] - nums[1] = 3 - 1 = 2
. - Calculate the previous difference
y = target[0] - nums[0] = 1 - 3 = -2
.
- Move to the next pair of elements:
-
Adjust Operations Based on Change in Difference:
- The differences
x
(positive) andy
(negative) have opposite signs, indicating a change in the trend. - Because the signs are different, add the absolute difference of the current element to
f
:f = f + abs(x) = 2 + 2 = 4
.
- The differences
-
Continue Iterating:
- For the next elements,
nums[2] = 2
andtarget[2] = 2
, the differencex = target[2] - nums[2] = 0
. - With no difference between them,
y
, calculated previously as2
(from step 3), becomes irrelevant as the difference is resolved.
- For the next elements,
-
Return Total Operations:
- After completing the iteration,
f
holds the value4
, representing the minimum number of operations needed.
- After completing the iteration,
This example illustrates the principle of monitoring changes in difference trends throughout nums
and target
, applying batch operations to efficiently match the arrays. Each adjustment is calculated based on the change in difference trends, aiming to minimize the total operation count.
Solution Implementation
1from typing import List
2
3class Solution:
4 def minimumOperations(self, nums: List[int], target: List[int]) -> int:
5 # Initialize the length of the list and the total operations needed
6 n = len(nums)
7
8 # Start with the initial difference between the first elements of target and nums
9 total_operations = abs(target[0] - nums[0])
10
11 # Iterate over the remaining elements
12 for i in range(1, n):
13 # Calculate the current difference and previous difference
14 current_difference = target[i] - nums[i]
15 previous_difference = target[i - 1] - nums[i - 1]
16
17 # If signs of the differences are the same (both positive or both negative)
18 if current_difference * previous_difference > 0:
19 # Calculate the additional operations needed
20 difference_in_operations = abs(current_difference) - abs(previous_difference)
21
22 # Add the additional operations only if it is positive
23 if difference_in_operations > 0:
24 total_operations += difference_in_operations
25 else:
26 # If signs differ, add the absolute value of the current difference
27 total_operations += abs(current_difference)
28
29 # Return the total number of operations needed
30 return total_operations
31
1class Solution {
2 public long minimumOperations(int[] nums, int[] target) {
3 // Initialize the operation count with the absolute difference of the first elements
4 long operations = Math.abs(target[0] - nums[0]);
5
6 // Traverse through the arrays starting from the second element
7 for (int i = 1; i < nums.length; ++i) {
8 // Calculate the difference for the current and previous elements
9 long currentDifference = target[i] - nums[i];
10 long previousDifference = target[i - 1] - nums[i - 1];
11
12 // Check if current and previous differences have the same sign
13 if (currentDifference * previousDifference > 0) {
14 // Calculate the difference in the absolute values
15 long differenceAdjustment = Math.abs(currentDifference) - Math.abs(previousDifference);
16
17 // If the absolute difference of the current is greater, add it to operations
18 if (differenceAdjustment > 0) {
19 operations += differenceAdjustment;
20 }
21 } else {
22 // Different signs mean a new sequence of operations is needed
23 operations += Math.abs(currentDifference);
24 }
25 }
26
27 // Return the total minimum operations needed
28 return operations;
29 }
30}
31
1class Solution {
2public:
3 long long minimumOperations(vector<int>& nums, vector<int>& target) {
4 using ll = long long; // Define a shorthand for long long type
5 ll operations = abs(target[0] - nums[0]); // Calculate the initial difference
6
7 // Traverse through the vectors from the second element onwards
8 for (int i = 1; i < nums.size(); ++i) {
9 long diff_current = target[i] - nums[i]; // Current difference
10 long diff_previous = target[i - 1] - nums[i - 1]; // Previous difference
11
12 // If both current and previous differences have the same sign
13 if (diff_current * diff_previous > 0) {
14 ll extra_needed = abs(diff_current) - abs(diff_previous);
15 // Add only the extra needed operations if current is greater in magnitude
16 if (extra_needed > 0) {
17 operations += extra_needed;
18 }
19 } else {
20 // If the signs differ, add the absolute of the current difference
21 operations += abs(diff_current);
22 }
23 }
24
25 return operations; // Return the total minimum operations required
26 }
27};
28
1/**
2 * Function to calculate the minimum operations needed to change nums array to match target array.
3 * An operation is defined as adjusting an element by incrementing or decrementing it.
4 * @param nums - The initial array of numbers.
5 * @param target - The target array of numbers.
6 * @returns The minimum number of operations needed.
7 */
8function minimumOperations(nums: number[], target: number[]): number {
9 // Get the length of the arrays (assuming both arrays have the same length)
10 const n = nums.length;
11
12 // Initialize the operations count with the difference of the first elements
13 let operations = Math.abs(target[0] - nums[0]);
14
15 // Loop through each element of the arrays starting from the second element
16 for (let i = 1; i < n; ++i) {
17 // Calculate the difference between current elements of target and nums
18 const currentDifference = target[i] - nums[i];
19
20 // Calculate the difference between previous elements of target and nums
21 const previousDifference = target[i - 1] - nums[i - 1];
22
23 // If the signs of current and previous differences are the same, adjust operations
24 if (currentDifference * previousDifference > 0) {
25 // Calculate the extra operations needed
26 const difference = Math.abs(currentDifference) - Math.abs(previousDifference);
27
28 // If extra operations are needed, add them to the total
29 if (difference > 0) {
30 operations += difference;
31 }
32 } else {
33 // If signs are different, add the absolute current difference to operations
34 operations += Math.abs(currentDifference);
35 }
36 }
37
38 // Return the calculated minimum number of operations
39 return operations;
40}
41
Time and Space Complexity
The given code calculates the minimum number of operations required to transform one list into another. The program iterates through the lists once, performing constant-time operations for each element. Hence, the time complexity is O(n)
, where n
is the length of the lists nums
and target
.
The space complexity is O(1)
since the algorithm uses only a fixed amount of additional space to store variables f
, x
, y
, and d
, regardless of the input size.
Learn more about how to find time and space complexity quickly.
Which of the following array represent a max heap?
Recommended Readings
Stack Intro Imagine you have a pile of books on your desk If you want to add a new book you place it on top If you want to read a book you take it from the top And if you simply want to see which book is on the top you
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
What is Dynamic Programming Prerequisite DFS problems dfs_intro Backtracking problems backtracking Memoization problems memoization_intro Pruning problems backtracking_pruning Dynamic programming is an algorithmic optimization technique that breaks down a complicated problem into smaller overlapping sub problems in a recursive manner and uses solutions to the sub problems to construct a solution
Want a Structured Path to Master System Design Too? Don’t Miss This!