Minimize the Sum of Absolute Costs of an Array Optimally
Last Updated :
18 Jan, 2024
Given an array arr[] of costs, your task is to minimize the sum of the absolute differences between consecutive costs by performing following operation at most once. Operation is that, we can select any index ‘i’ then make arr[i] = arr[i]/2.
Example:
Input: arr= [4,9,8]
Output: 4
Explanation: At index 0, 4 is halved now the array looks like = [2,9,8] and sum of absolute difference is abs(2-abs (9-8)= 8
At index 1, 9 is halved now the array looks like =[4,4,8] and sum of absolute difference is abs(4-abs (4-8)= 4
At index 2 8 is halved now the array looks like = [4,9,4] and sum of absolute difference is abs(4-abs (9-4)= 10
minimum of all absolute sums is 4.
Input: arr= [99,102,1,45,65]
Output: 161
Explanation: At index 0, 99 is halved now the array looks like = [49,102,1,45,65] and sum of absolute difference is 218
At index 1, 102 is halved now the array looks like = [99,51,1,45,65] and sum of absolute difference is 162
At index 2, 1 is halved now the array looks like = [99,102,0,45,65] and sum of absolute difference is 170
At index 3, 45 is halved now the array looks like = [99,102,1,22,65] and sum of absolute difference is 168
At index 4, 65 is halved now the array looks like = [99,102,1,45,32] and sum of absolute difference is 161
Approach:
We can solve this problem by just iterating the elements of an array and apply the operation on the element and store the minimum answer in any variable, this minimum value will be our resultant answer.
Steps to solve this problem:
- arr: The input array containing the costs.
- abs_arr: An array to store the absolute differences between consecutive costs.
- min_sum: A variable to keep track of the minimum sum of absolute differences. Initialize it with positive infinity to ensure it gets updated.
- Calculate the absolute differences between consecutive costs and store them in abs_arr. The first and last elements are initialized with 0 because they don’t have a previous or next element to compare with.
- Calculate the sum of the absolute differences and store it in the variable s.
- Iterate through each element of the arr array, considering the cost reductions for each element:
- If i-1 is less than 0, this means there is no previous element, so left_sum is set to 0.
- If i+1 is greater than the last index, this means there is no next element, so right_sum is set to 0.
- Otherwise, calculate left_sum as the absolute difference between the cost halved and the previous cost, and right_sum as the absolute difference between the cost halved and the next cost.
- Calculate the total sum of left_sum and right_sum for the current element. Calculate the sum_sofar as the total sum, including total, minus the absolute differences at the current and next elements (subtracting abs_arr[i] and abs_arr[i+1]).
- Update min_sum by taking the minimum of the current min_sum and sum_sofar. This tracks the minimum sum of absolute differences observed so far.
- After iterating through all elements in the array, min_sum will contain the minimum sum of absolute differences that can be achieved with the given cost reductions.
- Print the value of min_sum, which represents the minimum sum of absolute differences between consecutive costs.
Below is the implementation of the above problem:
C++
#include <iostream>
#include <vector>
#include <cmath>
#include <limits>
using namespace std;
int minimize_absolute_differences(vector< int >& arr) {
vector< int > abs_arr(arr.size() + 1, 0);
int min_sum = numeric_limits< int >::max();
for ( int i = 1; i < arr.size(); ++i) {
abs_arr[i] = abs (arr[i] - arr[i - 1]);
}
abs_arr[arr.size()] = 0;
int s = 0;
for ( int val : abs_arr) {
s += val;
}
for ( int i = 0; i < arr.size(); ++i) {
int left_sum, right_sum;
if (i - 1 < 0) {
left_sum = 0;
right_sum = abs ( floor (arr[i] / 2.0) - arr[i + 1]);
} else if (i + 1 > arr.size() - 1) {
right_sum = 0;
left_sum = abs ( floor (arr[i] / 2.0) - arr[i - 1]);
} else {
left_sum = abs ( floor (arr[i] / 2.0) - arr[i - 1]);
right_sum = abs ( floor (arr[i] / 2.0) - arr[i + 1]);
}
int total = left_sum + right_sum;
int sum_sofar = s + total - (abs_arr[i] + abs_arr[i + 1]);
min_sum = min(min_sum, sum_sofar);
}
return min_sum;
}
int main() {
vector< int > arr = {99, 102, 1, 45, 65};
int result = minimize_absolute_differences(arr);
cout << result << endl;
return 0;
}
|
Java
import java.util.Arrays;
public class MinimizeAbsoluteDifferences {
public static int minimizeAbsoluteDifferences( int [] arr) {
int [] absArr = new int [arr.length + 1 ];
int minSum = Integer.MAX_VALUE;
for ( int i = 1 ; i < arr.length; i++) {
absArr[i] = Math.abs(arr[i] - arr[i - 1 ]);
}
absArr[arr.length] = 0 ;
int s = Arrays.stream(absArr).sum();
for ( int i = 0 ; i < arr.length; i++) {
int leftSum, rightSum;
if (i - 1 < 0 ) {
leftSum = 0 ;
rightSum = Math.abs(( int ) Math.floor(arr[i] / 2.0 ) - arr[i + 1 ]);
} else if (i + 1 > arr.length - 1 ) {
rightSum = 0 ;
leftSum = Math.abs(( int ) Math.floor(arr[i] / 2.0 ) - arr[i - 1 ]);
} else {
leftSum = Math.abs(( int ) Math.floor(arr[i] / 2.0 ) - arr[i - 1 ]);
rightSum = Math.abs(( int ) Math.floor(arr[i] / 2.0 ) - arr[i + 1 ]);
}
int total = leftSum + rightSum;
int sumSoFar = s + total - (absArr[i] + absArr[i + 1 ]);
minSum = Math.min(minSum, sumSoFar);
}
return minSum;
}
public static void main(String[] args) {
int [] arr = { 99 , 102 , 1 , 45 , 65 };
int result = minimizeAbsoluteDifferences(arr);
System.out.println(result);
}
}
|
Python
import math
def minimize_absolute_differences(arr):
abs_arr = [ 0 ]
min_sum = float ( 'inf' )
for i in range ( 1 , len (arr)):
abs_arr.append( abs (arr[i] - arr[i - 1 ]))
abs_arr.append( 0 )
s = sum (abs_arr)
for i in range ( len (arr)):
if i - 1 < 0 :
left_sum = 0
right_sum = abs (math.floor(arr[i] / 2 ) - arr[i + 1 ])
elif i + 1 > len (arr) - 1 :
right_sum = 0
left_sum = abs (math.floor(arr[i] / 2 ) - arr[i - 1 ])
else :
left_sum = abs (math.floor(arr[i] / 2 ) - arr[i - 1 ])
right_sum = abs (math.floor(arr[i] / 2 ) - arr[i + 1 ])
total = left_sum + right_sum
sum_sofar = s + total - (abs_arr[i] + abs_arr[i + 1 ])
min_sum = min (min_sum, sum_sofar)
return min_sum
arr = [ 99 , 102 , 1 , 45 , 65 ]
result = minimize_absolute_differences(arr)
print (result)
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int MinimizeAbsoluteDifferences(List< int > arr)
{
List< int > absArr = new List< int >(arr.Count);
int minSum = int .MaxValue;
for ( int i = 1; i < arr.Count; i++)
{
absArr.Add(Math.Abs(arr[i] - arr[i - 1]));
}
int sum = 0;
foreach ( int val in absArr)
{
sum += val;
}
for ( int i = 0; i < arr.Count; i++)
{
int leftSum = 0, rightSum = 0;
if (i > 0)
{
leftSum = Math.Abs(( int )Math.Floor(arr[i] / 2.0) - arr[i - 1]);
}
if (i < arr.Count - 1)
{
rightSum = Math.Abs(( int )Math.Floor(arr[i] / 2.0) - arr[i + 1]);
}
int total = leftSum + rightSum;
int sumSoFar = sum +
total - (i > 0 ? absArr[i - 1] : 0) - (i < arr.Count - 1 ? absArr[i] : 0);
minSum = Math.Min(minSum, sumSoFar);
}
return minSum;
}
static void Main( string [] args)
{
List< int > arr = new List< int > { 99, 102, 1, 45, 65 };
int result = MinimizeAbsoluteDifferences(arr);
Console.WriteLine(result);
}
}
|
Javascript
function minimizeAbsoluteDifferences(arr) {
let absArr = [0];
let minSum = Infinity;
for (let i = 1; i < arr.length; i++) {
absArr.push(Math.abs(arr[i] - arr[i - 1]));
}
absArr.push(0);
let s = absArr.reduce((acc, val) => acc + val, 0);
for (let i = 0; i < arr.length; i++) {
let leftSum, rightSum;
if (i - 1 < 0) {
leftSum = 0;
rightSum = Math.abs(Math.floor(arr[i] / 2) - arr[i + 1]);
}
else if (i + 1 > arr.length - 1) {
rightSum = 0;
leftSum = Math.abs(Math.floor(arr[i] / 2) - arr[i - 1]);
}
else {
leftSum = Math.abs(Math.floor(arr[i] / 2) - arr[i - 1]);
rightSum = Math.abs(Math.floor(arr[i] / 2) - arr[i + 1]);
}
let total = leftSum + rightSum;
let sumSoFar = s + total - (absArr[i] + absArr[i + 1]);
minSum = Math.min(minSum, sumSoFar);
}
return minSum;
}
let arr = [99, 102, 1, 45, 65];
let result = minimizeAbsoluteDifferences(arr);
console.log(result);
|
Time Complexity: O(n)
Auxiliary space: O(n)
Share your thoughts in the comments
Please Login to comment...