Minimum Cost to Make Array Equalindromic — Medium Problem & Solution
You are given an integer array nums. You may change every element to one common value y, paying |nums[i] - y| for each element i.
- Difficulty: Medium
- Topics: Arrays, Math, Greedy, Sorting
- Asked at: Amazon, Google
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
You are given an integer array nums. You may change every element to one common value y, paying |nums[i] - y| for each element i.
The array is equalindromic when all its elements equal the same palindromic positive integer — a number that reads the same forwards and backwards in base 10, such as 7, 44 or 121.
Return the minimum total cost to make nums equalindromic.
The original allows up to 10^5 values of up to 10^9; here n <= 10^4 and values are at most 10^5, so the cost always fits in a 32-bit integer.
Example 1
Input: nums = [10,12,13,14,15]
Output: 11
Explanation: Change everything to the palindrome 11: 1 + 1 + 2 + 3 + 4 = 11.
Example 2
Input: nums = [101,104,99,250]
Output: 154
Explanation: Choosing 101 costs 0 + 3 + 2 + 149.
Example 3
Input: nums = [22,33,22,33,22]
Output: 22
Constraints
1 <= nums.length <= 10^41 <= nums[i] <= 10^5
How to solve Minimum Cost to Make Array Equalindromic
The cost f(y) = sum |nums[i] - y| is convex and minimised at the median. Moving away from the median in either direction never helps, so the best palindrome is one of the two palindromes that bracket the median.
Approach
- Sort
numsand take the medianm = nums[n / 2]. - Step down from
muntil reaching a palindromelo, and up frommuntil reaching a palindromehi. - Return
min(f(lo), f(hi)), computing each sum in 64-bit arithmetic.
Why it works
f is flat between the two middle elements and strictly sloped outside them, so it is non-increasing up to the median and non-decreasing after it. Any palindrome below lo costs at least f(lo), and any palindrome above hi costs at least f(hi). Palindromes are dense enough (gaps of at most 110 below 10^5) that the stepping is short.
Complexity
- Time —
O(n log n) - Space —
O(n)
Pitfalls
- Checking only the nearest palindrome to the median by distance is wrong — compare the costs of both neighbours.
- With an even length either middle element works as the median, because
fis flat between them. - Accumulate the cost in 64 bits in fixed-width languages even though the tightened answer fits in int32.
Reference solution
Python
from typing import List
def minimumCost(nums: List[int]) -> int:
a = sorted(nums)
med = a[len(a) // 2]
def is_pal(x):
s = str(x)
return s == s[::-1]
lo = med
while not is_pal(lo):
lo -= 1
hi = med
while not is_pal(hi):
hi += 1
return min(sum(abs(v - lo) for v in a), sum(abs(v - hi) for v in a))JavaScript
var minimumCost = function(nums) {
var a = nums.slice().sort(function(x, y) { return x - y; });
var med = a[a.length >> 1];
var isPal = function(x) {
var r = 0, t = x;
while (t > 0) { r = r * 10 + (t % 10); t = Math.floor(t / 10); }
return r === x;
};
var cost = function(y) {
var s = 0;
for (var i = 0; i < a.length; i++) s += Math.abs(a[i] - y);
return s;
};
var lo = med, hi = med;
while (!isPal(lo)) lo--;
while (!isPal(hi)) hi++;
return Math.min(cost(lo), cost(hi));
};Also on the editorial tab: C, C#, C++, Go, Java, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 988 arrays problems · the whole catalogue
Learn the technique: Arrays · Greedy Algorithms