leetcode
leetcode 2101 ~ 2150
使数组相等的最小开销

使数组相等的最小开销

难度:

标签:

题目描述

代码结果

运行时间: 64 ms, 内存: 35.3 MB


/*
 * 思路:
 * 1. 使用Java Stream来简化计算和代码。
 * 2. 通过二分查找找到使总开销最小的目标值。
 * 3. 使用流来计算每个目标值对应的总开销。
 */
import java.util.stream.IntStream;

public class Solution {
    public long minCost(int[] nums, int[] cost) {
        int left = 1, right = 1000000;
        while (left < right) {
            int mid = (left + right) / 2;
            long cost1 = getCost(nums, cost, mid);
            long cost2 = getCost(nums, cost, mid + 1);
            if (cost1 > cost2) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return getCost(nums, cost, left);
    }

    private long getCost(int[] nums, int[] cost, int target) {
        return IntStream.range(0, nums.length)
                        .mapToLong(i -> (long) Math.abs(nums[i] - target) * cost[i])
                        .sum();
    }
}

解释

方法:

这个题解利用了"成本加权中位数"的概念来找到一个目标值,使得将所有数组元素变成这个值的总成本最小。首先通过对数组nums和cost的zip操作合并,然后根据nums值进行排序。排序后,计算累积成本直到超过总成本的一半,此时对应的nums中的值作为目标值最佳。最后,计算使所有nums元素变为此目标值的成本和。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
题解中提到了'成本加权中位数',能否详细解释这个概念是如何应用在这个问题上的?
成本加权中位数是一种考虑权重的中位数,其中权重是每个元素对目标值影响的重要性或成本。在这个问题中,数组中的每个元素nums[i]有一个相应的成本cost[i]。算法的目标是找到一个数值,使得将所有nums元素调整到这个数值的总成本最小。通过将元素和它们的成本结合起来考虑,然后排序并计算累积成本,直到这个累积值超过总成本的一半。这时候的nums元素值即为成本加权中位数,因为在该点,一半以上的成本集中在这个值及之前的值上,使得成本最小化。
🦆
在题解中,为什么在累积成本超过总成本的一半时,此时的`nums`值就能作为最佳目标值?
在累积成本超过总成本的一半时,选定的`nums`值作为目标值可以最小化总变动成本。这是因为,在此点之前和之后的元素需要向这个点调整,而由于累积成本刚好超过一半,这保证了大部分的调整成本(即权重)都集中在距离这个目标值较近的数值上,从而减少了总调整成本。
🦆
题解中排序的目的是什么,对算法的正确性和效率有什么影响?
排序的目的是为了按照值的顺序处理元素,从而可以逐步累加成本,并找到成本加权中位数。排序确保我们可以正确地计算出在哪一点累积成本超过总成本的一半,这是找到最佳目标值的关键。排序对算法的效率有影响,因为排序操作通常是O(n log n)的时间复杂度,这可能是整个算法中最耗时的部分,但它是实现这种最小化成本方法的必要步骤。
🦆
如果数组`nums`所有元素相等,题解中的算法是否还会有效,会有什么特殊情况?
如果数组`nums`中的所有元素相等,题解的算法仍然有效且更为简化。因为所有元素已经相等,所以不需要任何调整,整个数组已经是关于任何成本加权中位数的最小开销状态。在这种情况下,算法在计算总成本之后,会立即发现所有元素已经处于目标值,因此返回的总成本将是零。

相关问题