Minimize the maximum difference between the heights
Given an array arr[] representing the heights of towers and a positive integer k, we can modify each tower’s height exactly once by either adding k or subtracting k. After these modifications, find the minimum possible difference between the tallest and the shortest tower.
Note: It is compulsory to increase or decrease the height by k for each tower. After the operation, the resultant array should not contain any negative integers.
Examples:
Input: k = 2, arr[] = [1, 5, 8, 10]
Output: 5
Explanation: The array can be modified as [1+k, 5-k, 8-k, 10-k]= [3, 3, 6, 8]. The difference between the largest and the smallest is 8 - 3 = 5.Input: k = 3, arr[] = [3, 9, 12, 16, 20]
Output: 11
Explanation: The array can be modified as [3+k, 9+k, 12-k, 16-k, 20-k] = [6, 12, 9, 13, 17]. The difference between the largest and the smallest is 17 - 6 = 11.
[Approach] Using Sorting - O(n logn) Time and O(1) Space
We bring the towers closer by increasing the shorter ones and decreasing the taller ones. After sorting, we try splitting the array at some point: towers on the left are increased by +k, and towers on the right are decreased by -k.
Why this works:
The new minimum and maximum can only come from these boundaries. So by checking all split points, we cover every case and guarantee the minimum possible difference.
Steps to solve the problem:
- Sort the array arr in non-decreasing order.
- Initialize ans = arr[n-1] - arr[0].
- Precompute smallest = arr[0] + k and largest = arr[n-1] - k.
- Loop for i = 1 to n-1:
=> If arr[i] - k < 0, continue (heights can’t be negative).
=> minH = min(smallest, arr[i] - k).
=> maxH = max(largest, arr[i-1] + k).
=> ans = min(ans, maxH - minH). - Return ans.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int getMinDiff(vector<int> &arr, int k) {
int n = arr.size();
sort(arr.begin(), arr.end());
int res = arr[n - 1] - arr[0];
// For all indices i, increment
// arr[0...i-1] by k and decrement and arr[i...n-1] by k
for (int i = 1; i < n; i++) {
// Impossible to decrement
// height of ith tower by k, continue
if (arr[i] - k < 0)
continue;
int minH = min(arr[0] + k, arr[i] - k);
int maxH = max(arr[i - 1] + k, arr[n - 1] - k);
res = min(res, maxH - minH);
}
return res;
}
int main() {
int k = 2;
vector<int> arr = {1, 5, 8, 10};
int ans = getMinDiff(arr, k);
cout << ans;
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdlib.h> // For qsort
int compare(const void *a, const void *b)
{
return (*(int*)a - *(int*)b);
}
int getMinDiff(int arr[], int n, int k)
{
int res = arr[n - 1] - arr[0];
// Sort the array using qsort
qsort(arr, n, sizeof(int), compare);
// For all indices i, increment
// arr[0...i-1] by k and decrement and arr[i...n-1] by k
for (int i = 1; i < n; i++)
{
// Impossible to decrement height of ith tower by k, continue
if (arr[i] - k < 0)
continue;
int minH = (arr[0] + k < arr[i] - k) ? arr[0] + k : arr[i] - k;
int maxH = (arr[i - 1] + k > arr[n - 1] - k) ? arr[i - 1] + k : arr[n - 1] - k;
res = (res > maxH - minH) ? maxH - minH : res;
}
return res;
}
int main()
{
int k = 2;
int arr[] = {1, 5, 8, 10};
int n = sizeof(arr) / sizeof(arr[0]);
int ans = getMinDiff(arr, n, k);
printf("%d", ans);
return 0;
}
import java.util.Arrays;
class GfG {
static int getMinDiff(int[] arr, int k) {
int n = arr.length;
Arrays.sort(arr);
int res = arr[n - 1] - arr[0];
// For all indices i, increment arr[0...i-1] by k and
// decrement arr[i...n-1] by k
for (int i = 1; i < arr.length; i++) {
// Impossible to decrement height of ith tower by k, continue
if (arr[i] - k < 0)
continue;
int minH = Math.min(arr[0] + k, arr[i] - k);
int maxH = Math.max(arr[i - 1] + k, arr[n - 1] - k);
res = Math.min(res, maxH - minH);
}
return res;
}
public static void main(String[] args) {
int k = 2;
int[] arr = {1, 5, 8, 10};
int ans = getMinDiff(arr, k);
System.out.println(ans);
}
}
def getMinDiff(arr, k):
n = len(arr)
arr.sort()
res = arr[n - 1] - arr[0]
# For all indices i, increment
# arr[0...i-1] by k and decrement arr[i...n-1] by k
for i in range(1, len(arr)):
# Impossible to decrement height of ith tower by k, continue
if arr[i] - k < 0:
continue
minH = min(arr[0] + k, arr[i] - k)
maxH = max(arr[i - 1] + k, arr[n - 1] - k)
res = min(res, maxH - minH)
return res
if __name__ == "__main__":
k = 2
arr = [1, 5, 8, 10]
ans = getMinDiff(arr, k)
print(ans)
using System;
class GfG {
public static int getMinDiff(int[] arr, int k) {
int n = arr.Length;
Array.Sort(arr);
int res = arr[n - 1] - arr[0];
// For all indices i, increment
// arr[0...i-1] by k and decrement arr[i...n-1] by k
for (int i = 1; i < arr.Length; i++) {
// Impossible to decrement height of ith tower by k, continue
if (arr[i] - k < 0)
continue;
int minH = Math.Min(arr[0] + k, arr[i] - k);
int maxH = Math.Max(arr[i - 1] + k, arr[n - 1] - k);
res = Math.Min(res, maxH - minH);
}
return res;
}
static void Main() {
int k = 2;
int[] arr = {1, 5, 8, 10};
int ans = getMinDiff(arr, k);
Console.WriteLine(ans);
}
}
function getMinDiff(arr, k) {
const n = arr.length;
arr.sort((a, b) => a - b);
let res = arr[n - 1] - arr[0];
// For all indices i, increment arr[0...i-1]
// by k and decrement arr[i...n-1] by k
for (let i = 1; i < arr.length; i++) {
// Impossible to decrement height of ith tower by k, continue
if (arr[i] - k < 0)
continue;
let minH = Math.min(arr[0] + k, arr[i] - k);
let maxH = Math.max(arr[i - 1] + k, arr[n - 1] - k);
res = Math.min(res, maxH - minH);
}
return res;
}
// Driver Code
const k = 2;
const arr = [1, 5, 8, 10];
const ans = getMinDiff(arr, k);
console.log(ans);
Output
5