leetcode
leetcode 2701 ~ 2750
使数组成为等数数组的最小代价

使数组成为等数数组的最小代价

难度:

标签:

题目描述

You are given a 0-indexed integer array nums having length n.

You are allowed to perform a special move any number of times (including zero) on nums. In one special move you perform the following steps in order:

  • Choose an index i in the range [0, n - 1], and a positive integer x.
  • Add |nums[i] - x| to the total cost.
  • Change the value of nums[i] to x.

A palindromic number is a positive integer that remains the same when its digits are reversed. For example, 121, 2552 and 65756 are palindromic numbers whereas 24, 46, 235 are not palindromic numbers.

An array is considered equalindromic if all the elements in the array are equal to an integer y, where y is a palindromic number less than 109.

Return an integer denoting the minimum possible total cost to make nums equalindromic by performing any number of special moves.

 

Example 1:

Input: nums = [1,2,3,4,5]
Output: 6
Explanation: We can make the array equalindromic by changing all elements to 3 which is a palindromic number. The cost of changing the array to [3,3,3,3,3] using 4 special moves is given by |1 - 3| + |2 - 3| + |4 - 3| + |5 - 3| = 6.
It can be shown that changing all elements to any palindromic number other than 3 cannot be achieved at a lower cost.

Example 2:

Input: nums = [10,12,13,14,15]
Output: 11
Explanation: We can make the array equalindromic by changing all elements to 11 which is a palindromic number. The cost of changing the array to [11,11,11,11,11] using 5 special moves is given by |10 - 11| + |12 - 11| + |13 - 11| + |14 - 11| + |15 - 11| = 11.
It can be shown that changing all elements to any palindromic number other than 11 cannot be achieved at a lower cost.

Example 3:

Input: nums = [22,33,22,33,22]
Output: 22
Explanation: We can make the array equalindromic by changing all elements to 22 which is a palindromic number. The cost of changing the array to [22,22,22,22,22] using 2 special moves is given by |33 - 22| + |33 - 22| = 22.
It can be shown that changing all elements to any palindromic number other than 22 cannot be achieved at a lower cost.

 

Constraints:

  • 1 <= n <= 105
  • 1 <= nums[i] <= 109

代码结果

运行时间: 87 ms, 内存: 30.4 MB


/*
题目思路:
1. 使用流操作生成所有小于 10^9 的回文数。
2. 对于每个可能的回文数,计算将数组 nums 中的所有元素变为该回文数的总代价。
3. 返回最小的总代价。
*/

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class PalindromeArrayStream {
    // 使用流生成所有小于 10^9 的回文数
    public static List<Integer> generatePalindromes() {
        return IntStream.range(1, 10).boxed()
                .flatMap(i -> IntStream.range(0, 10).boxed()
                        .flatMap(j -> IntStream.range(0, 10).boxed()
                                .flatMap(k -> List.of(i * 100 + j * 10 + i, i * 1000 + j * 100 + j * 10 + i).stream())
                        )
                ).collect(Collectors.toList());
    }

    public static int minCost(int[] nums) {
        List<Integer> palindromes = generatePalindromes();
        return palindromes.stream().mapToInt(p -> IntStream.of(nums).map(num -> Math.abs(num - p)).sum()).min().orElse(Integer.MAX_VALUE);
    }

    public static void main(String[] args) {
        int[] nums = {10, 12, 13, 14, 15};
        System.out.println(minCost(nums)); // 输出 11
    }
}

解释

方法:

此题解首先对数组进行排序,从而简化找到最佳回文数目标值的过程。利用中位数或接近中位数的值作为可能的目标回文数是一个高效的策略,因为中位数附近的值在优化总距离和上是很有帮助的。接着,题解定义了两个辅助函数 bigger 和 smaller 来计算给定数值的最近大回文数和最近小回文数。这些函数通过字符串操作检查并构造回文数。最后,题解通过计算将所有数组元素变为这两个回文数(由中位数计算得到)的代价,并返回较小的一个,从而实现了找到最小总代价的目标。

时间复杂度:

O(n log n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在选择目标回文数时,选择了中位数附近的数值而不是平均数或其他统计值?
在优化整体代价的问题中,使用中位数作为目标值可以最小化所有元素与此目标的绝对差值的总和。相对于平均数,中位数对异常值不敏感,因此能更好地表示数据的中心趋势,特别是在需要考虑距离和时。在本题中,我们的目标是将所有数转换为回文数,而选择中位数附近的数作为目标回文数可以有效减少转换的总代价,因为中位数本身就处于数组的中间位置,从而使得总距离最小化。
🦆
在`bigger`和`smaller`函数中,如何确保构造的数字确实是最接近的大回文数或小回文数,而不只是一个简单的回文数?
在`bigger`和`smaller`函数中,通过构造回文数后,会进行比较以确保生成的回文数是大于或小于原始数字的最接近的回文数。如果构造出的回文数不符合要求(例如,不是最接近的大回文数或小回文数),则调整中间部分的数字(增大或减小),再重新构造回文数进行比较。这种方法通过直接构造并调整来确保结果是最接近的大回文数或小回文数。这种策略确保了构造的回文数既符合大小要求,也是距离最近的有效回文数。
🦆
对于边界情况,例如所有数字都是极小或极大值时,这种基于中位数的方法是否仍然有效?
即使在所有数值都是极小值或极大值的边界情况下,基于中位数的方法仍然有效。中位数的定义本质上是排序后位于中间的数值,因此无论数组中的数值如何极端,中位数总是有效地反映了数组的中心位置。在这种情况下,将数组中的数转换为基于中位数的回文数可能依然是最优解,因为这样的转换总体上确保了最小的代价。但是,需要注意的是,如果所有数值极端相同,转换成任何一个回文数的成本都会是一样的,因此这种情况下选择哪一个回文数将不会影响总代价。

相关问题