Most Efficient Approach ( Median Approach Using Quickselect)
Choose the last element as the pivot, initialize a partition index, and traverse the array. Swap elements less than or equal to the pivot with the partition index element, then place the pivot at the partition index and return it. In Quickselect, if the left index equals the right index, return that element. Partition the array and get the partition index. If it matches k, return the element at k. Recursively call Quickselect on the left or right part based on k’s position relative to the partition index. Copy the original array, use Quickselect to find the median, and iterate through the array to calculate the sum of absolute differences with the median.
Below is the implementation of above approach
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
// Function to partition the array around a pivot
int partition(vector<int>& nums, int left, int right) {
int pivot = nums[right];
int pIndex = left;
for (int i = left; i < right; ++i) {
if (nums[i] <= pivot) {
swap(nums[i], nums[pIndex]);
pIndex++;
}
}
swap(nums[pIndex], nums[right]);
return pIndex;
}
// Quickselect function to find the k-th smallest element
int quickSelect(vector<int>& nums, int left, int right, int k) {
if (left == right) return nums[left];
int pIndex = partition(nums, left, right);
if (k == pIndex) return nums[k];
else if (k < pIndex) return quickSelect(nums, left, pIndex - 1, k);
else return quickSelect(nums, pIndex + 1, right, k);
}
// Function to find the minimum sum of absolute differences
int minSumOfAbsoluteDifferences(const vector<int>& arr) {
vector<int> nums = arr;
int median = quickSelect(nums, 0, nums.size() - 1, nums.size() / 2);
int minSum = 0;
for (int i : arr) {
minSum += abs(i - median);
}
return minSum;
}
int main() {
vector<int> arr = {2, 5, 1, 7, 4};
cout << "Minimum sum of absolute differences: " << minSumOfAbsoluteDifferences(arr) << endl;
return 0;
}
import java.util.Arrays;
public class Main {
// Function to partition the array around a pivot
public static int partition(int[] nums, int left, int right) {
int pivot = nums[right];
int pIndex = left;
for (int i = left; i < right; ++i) {
if (nums[i] <= pivot) {
int temp = nums[i];
nums[i] = nums[pIndex];
nums[pIndex] = temp;
pIndex++;
}
}
int temp = nums[pIndex];
nums[pIndex] = nums[right];
nums[right] = temp;
return pIndex;
}
// Quickselect function to find the k-th smallest element
public static int quickSelect(int[] nums, int left, int right, int k) {
if (left == right) return nums[left];
int pIndex = partition(nums, left, right);
if (k == pIndex) return nums[k];
else if (k < pIndex) return quickSelect(nums, left, pIndex - 1, k);
else return quickSelect(nums, pIndex + 1, right, k);
}
// Function to find the minimum sum of absolute differences
public static int minSumOfAbsoluteDifferences(int[] arr) {
int[] nums = Arrays.copyOf(arr, arr.length);
int median = quickSelect(nums, 0, nums.length - 1, nums.length / 2);
int minSum = 0;
for (int i : arr) {
minSum += Math.abs(i - median);
}
return minSum;
}
public static void main(String[] args) {
int[] arr = {2, 5, 1, 7, 4};
System.out.println("Minimum sum of absolute differences: " + minSumOfAbsoluteDifferences(arr));
}
}
// This code is contributed by Ayush Mishra
Output
Minimum sum of absolute differences: 9
Time Complexity: O(n)
Space Complexity: O(n)
We can further optimize the above solution to O(n) by using linear time algorithm for median finding.
Minimum sum of differences with an element in an array
Given an array, we need to find the sum of elements of an array after changing the element as arr[i] will become abs(arr[i]-x) where x is an array element.
Examples:
Input : {2, 5, 1, 7, 4}
Output : 9
We get minimum sum when we choose
x = 4. The minimum sum is
abs(2-4) + abs(5-4) + abs(1-4) + (7-4)
abs(4-4) = 9
Input : {5, 11, 14, 10, 17, 15}
Output : 20
We can either choose x = 14 or x = 11
Naive Approach:
The naive approach to solve the problem can be like: We pick each element of the array and then traverse entire array to store sum of absolute difference of the picked element and ith element. After traversal of the array, we keep updating a variable say res with minimum of the current sum that we get after traversal and the previous value that variable res will be having. Finally, after going through each element of the array the same way we will be having our answer in res variable.
Algorithm:
- Define a function “findSum” which takes an integer array “arr”, its size “n” and an integer “x” as input.
- Initialize a variable “res” to a very large number.
- For each element “i” in the array “arr”, do the following:
a. Initialize a variable “sum” to 0.
b. For each element “j” in the array “arr”, do the following:
i. Calculate the absolute difference between the elements “arr[i]” and “arr[j]”. This can be done by subtracting “arr[j]” from “arr[i]” and taking the absolute value of the result using the “abs()” function.
ii. Add this absolute difference to the variable “sum”.
c. If the value of “sum” is less than the current value of “res”, update the value of “res” to “sum”.
4. Return the value of “res”.
Below is the implementation of the approach:
// C++ code for the approach
#include <bits/stdc++.h>
using namespace std;
// Function to calculate sum of absolute differences
int calculateSum(int arr[], int n, int x) {
int sum = 0;
// traverse to find sum of absolute differences
for (int i = 0; i < n; i++) {
sum += abs(arr[i] - x);
}
return sum;
}
// Function to find minimum sum of absolute differences
int findMinSum(int arr[], int n) {
// variable to store the minimum result value
int res = INT_MAX;
// traverse through each element to
// find sum of absolute difference
// of all elements with it
for (int i = 0; i < n; i++) {
// Function call
int sum = calculateSum(arr, n, arr[i]);
// update res with the minimum one
res = min(res, sum);
}
return res;
}
// Driver's Code
int main() {
// Input
int arr[] = { 5, 11, 14, 10, 17, 15 };
int n = sizeof(arr) / sizeof(arr[0]);
// Function call
int minSum = findMinSum(arr, n);
cout << minSum << endl;
return 0;
}
public class Main {
// Function to calculate the sum of absolute differences
static int calculateSum(int[] arr, int n, int x) {
int sum = 0;
// Traverse to find the sum of absolute differences
for (int i = 0; i < n; i++) {
sum += Math.abs(arr[i] - x);
}
return sum;
}
// Function to find the minimum sum of absolute differences
static int findMinSum(int[] arr, int n) {
// Variable to store the minimum result value
int res = Integer.MAX_VALUE;
// Traverse through each element to
// find the sum of absolute difference
// of all elements with it
for (int i = 0; i < n; i++) {
// Function call
int sum = calculateSum(arr, n, arr[i]);
// Update res with the minimum one
res = Math.min(res, sum);
}
return res;
}
public static void main(String[] args) {
// Input
int[] arr = { 5, 11, 14, 10, 17, 15 };
int n = arr.length;
// Function call
int minSum = findMinSum(arr, n);
System.out.println(minSum);
}
}
# Function to calculate sum of absolute differences
def calculateSum(arr, n, x):
sum = 0
# traverse to find sum of absolute differences
for i in range(n):
sum += abs(arr[i] - x)
return sum
# Function to find minimum sum of absolute differences
def findMinSum(arr, n):
# variable to store the minimum result value
res = float('inf')
# traverse through each element to
# find sum of absolute difference
# of all elements with it
for i in range(n):
# Function call
sum = calculateSum(arr, n, arr[i])
# update res with the minimum one
res = min(res, sum)
return res
# Driver Code
if __name__ == '__main__':
# Input
arr = [5, 11, 14, 10, 17, 15]
n = len(arr)
# Function call
minSum = findMinSum(arr, n)
print(minSum)
using System;
class Program {
// Function to calculate the sum of absolute differences
static int CalculateSum(int[] arr, int n, int x)
{
int sum = 0;
// Traverse to find the sum of absolute differences
for (int i = 0; i < n; i++) {
sum += Math.Abs(arr[i] - x);
}
return sum;
}
// Function to find the minimum sum of absolute
// differences
static int FindMinSum(int[] arr, int n)
{
// Variable to store the minimum result value
int res = int.MaxValue;
// Traverse through each element to
// find the sum of absolute difference
// of all elements with it
for (int i = 0; i < n; i++) {
// Function call
int sum = CalculateSum(arr, n, arr[i]);
// Update res with the minimum one
res = Math.Min(res, sum);
}
return res;
}
static void Main()
{
// Input
int[] arr = { 5, 11, 14, 10, 17, 15 };
int n = arr.Length;
// Function call
int minSum = FindMinSum(arr, n);
Console.WriteLine(minSum);
}
}
// Function to calculate sum of absolute differences
function calculateSum(arr, n, x) {
let sum = 0;
// Traverse to find sum of absolute differences
for (let i = 0; i < n; i++) {
sum += Math.abs(arr[i] - x);
}
return sum;
}
// Function to find minimum sum of absolute differences
function findMinSum(arr, n) {
// Variable to store the minimum result value
let res = Number.MAX_SAFE_INTEGER;
// Traverse through each element to
// find sum of absolute difference
// of all elements with it
for (let i = 0; i < n; i++) {
// Function call
let sum = calculateSum(arr, n, arr[i]);
// Update res with the minimum one
res = Math.min(res, sum);
}
return res;
}
// Driver's Code
// Input
let arr = [5, 11, 14, 10, 17, 15];
let n = arr.length;
// Function call
let minSum = findMinSum(arr, n);
console.log(minSum);
Output
20
Time Complexity: O(n*n) as two nested for loops is basically executing in total. Here, n is size of the input array.
Auxiliary Space: O(1) as no extra space has been used.
Efficient Approach:
The idea is based on fact that middle element would cause minimum sum of differences. When there are even number of elements, we can take any of the middle two elements. We can verify this fact by taking few examples.
Implementation:
// C++ program to find minimum sum of absolute
// differences with an array element.
#include<bits/stdc++.h>
using namespace std;
// function to find min sum after operation
int absSumDidd(int a[],int n)
{
// Sort the array
sort(a,a+n);
// Pick middle value
int midValue = a[(int)(n / 2)];
// Sum of absolute differences.
int sum = 0;
for (int i = 0; i < n; i++) {
sum = sum + abs(a[i] - midValue);
}
return sum;
}
// Driver Code
int main()
{
int arr[] = { 5, 11, 14, 10, 17, 15 };
int n=sizeof(arr)/sizeof(arr[0]);
cout<< absSumDidd(arr,n);
}
// Contributed by mits
// Java program to find minimum sum of absolute
// differences with an array element.
import java.lang.*;
import java.util.*;
public class GFG {
// function to find min sum after operation
static int absSumDidd(int a[])
{
// Sort the array
Arrays.sort(a);
// Pick middle value
int midValue = a[a.length / 2];
// Sum of absolute differences.
int sum = 0;
for (int i = 0; i < a.length; i++) {
sum = sum + Math.abs(a[i] - midValue);
}
return sum;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 5, 11, 14, 10, 17, 15 };
System.out.print(absSumDidd(arr));
}
// Contributed by Saurav Jain
}
# Python3 program to find minimum sum of
# absolute differences with an array element.
# function to find min sum after operation
def absSumDidd(a, n):
# Sort the array
a.sort()
# Pick middle value
midValue = a[(int)(n // 2)]
# Sum of absolute differences.
sum = 0
for i in range(n):
sum = sum + abs(a[i] - midValue)
return sum
# Driver Code
arr = [5, 11, 14, 10, 17, 15]
n = len(arr)
print(absSumDidd(arr, n))
# This code is contributed
# by sahishelangia
// C# program to find minimum sum of absolute
// differences with an array element.
using System;
class GFG {
// function to find min sum after operation
static int absSumDidd(int []a)
{
// Sort the array
Array.Sort(a);
// Pick middle value
int midValue = a[a.Length / 2];
// Sum of absolute differences.
int sum = 0;
for (int i = 0; i < a.Length; i++) {
sum = sum + Math.Abs(a[i] - midValue);
}
return sum;
}
// Driver Code
public static void Main()
{
int []arr = { 5, 11, 14, 10, 17, 15 };
Console.Write(absSumDidd(arr));
}
// Contributed by Subhadeep
}
<script>
// Javascript program to find minimum sum of absolute
// differences with an array element.
// Function to find min sum after operation
function absSumDidd(a)
{
// Sort the array
a.sort((a, b) => a - b);
// Pick middle value
var midValue = a[a.length / 2];
// Sum of absolute differences.
var sum = 0;
for(var i = 0; i < a.length; i++)
{
sum = sum + Math.abs(a[i] - midValue);
}
return sum;
}
// Driver Code
var arr = [ 5, 11, 14, 10, 17, 15 ];
document.write(absSumDidd(arr));
// This code is contributed by shikhasingrajput
</script>
<?php
// PHP program to find minimum
// sum of absolute differences
// with an array element.
// function to find min sum
// after operation
function absSumDidd($a, $n)
{
// Sort the array
sort($a);
// Pick middle value
$midValue = $a[($n / 2)];
// Sum of absolute differences.
$sum = 0;
for ( $i = 0; $i < $n; $i++)
{
$sum = $sum + abs($a[$i] -
$midValue);
}
return $sum;
}
// Driver Code
$arr = array(5, 11, 14, 10, 17, 15 );
$n = count($arr);
echo absSumDidd($arr, $n);
// This code is contributed
// by anuj_67
?>
Output
20
Time Complexity: O(n Log n)
Auxiliary Space: O(1), as we are only using constant space to store some variables.