leetcode
leetcode 2001 ~ 2050
最小差值平方和

最小差值平方和

难度:

标签:

题目描述

代码结果

运行时间: 116 ms, 内存: 31.2 MB


/*
 * 思路:
 * 1. 计算初始差值平方和。
 * 2. 使用 Java Stream 将 nums1 和 nums2 对应位置元素的差值的绝对值存储在一个列表中。
 * 3. 根据 k1 和 k2 的总和调整最大的差值,减少差值平方和。
 * 4. 最后计算调整后的差值平方和。
 */

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

public class Solution {
    public long minSumSquareDiff(int[] nums1, int[] nums2, int k1, int k2) {
        int n = nums1.length;
        List<Integer> diffs = IntStream.range(0, n)
                .map(i -> Math.abs(nums1[i] - nums2[i]))
                .boxed()
                .sorted((a, b) -> b - a)
                .collect(Collectors.toList());

        long initialSum = diffs.stream().mapToLong(diff -> (long) diff * diff).sum();
        int totalK = k1 + k2;
        
        for (int i = 0; i < n && totalK > 0; i++) {
            if (diffs.get(i) > 0) {
                int newDiff = Math.max(0, diffs.get(i) - 1);
                initialSum -= (long) diffs.get(i) * diffs.get(i);
                initialSum += (long) newDiff * newDiff;
                diffs.set(i, newDiff);
                totalK--;
            }
        }
        
        return initialSum;
    }
}

解释

方法:

首先,计算两个数组中对应元素的差的绝对值,并将这些差值存储在一个列表中。然后对这个差值列表进行降序排序,以便优先考虑减少最大差值的平方。接着,尝试使用可用的操作次数(k1 + k2)来减少这些差值。从最大的差值开始,一步一步使用操作次数来尽量减少差值。如果所有的操作次数用完或者差值已经减至最小(即为0),则退出。最后,计算调整后的差值平方和。这种方法通过优先减少最大的差值,来尽可能降低总的差值平方和。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
在题解中,为什么在减少差值时选择将差值数组进行降序排序?这种排序方式对最终结果的影响是什么?
在题解中,选择将差值数组进行降序排序是为了优先减少最大的差值。由于目标是最小化所有差值的平方和,而平方函数是一个非线性增长的函数,因此较大的差值对总平方和的贡献更大。通过优先减少这些较大的差值,可以更有效地减少总的平方和。这种排序方式使得可以更有策略地使用有限的操作次数,以实现对总平方和的最大可能降低。
🦆
题解中提到了在操作次数不足以继续减少当前差值时会停止调整,但这种情况下是否考虑了更有效的分配剩余操作次数以最小化平方和的可能性?
题解中的方法在操作次数不足以继续减少当前的最大差值时确实停止了进一步的减少,并进行了一次均匀分配,使得剩余的操作次数尽可能均匀地分配在当前未处理的最大差值上。虽然这种方法简化了处理流程,并在很多情况下能有效地减少平方和,但它可能不是在所有情况下都最优的。例如,可能存在通过将所有剩余操作次数集中在少数几个较大的差值上,而不是均匀分配,能够得到更小的总平方和的情况。
🦆
在实现中使用了一个边界值`nums.append(0)`,这一步骤具体是为了解决什么问题?
在实现中添加`nums.append(0)`作为边界值是为了处理所有差值都被减至0或当操作次数用完时的情况。这个边界值简化了循环和条件判断,使得在减少最后一个差值时不需要特别处理数组越界的问题。它确保了在减少每个差值时可以方便地引用`nums[i+1]`,并正确计算接下来需要减少的差值数量,避免了代码中可能出现的错误和复杂性。
🦆
题解中提到的操作次数`k`是`k1 + k2`的总和,这种处理方式是否意味着不区分修改`nums1`或`nums2`的次数限制?这种策略在所有情况下都是最优的吗?
题解中将操作次数`k`视为`k1 + k2`的总和,确实意味着在调整过程中不区分修改`nums1`或`nums2`的次数限制。这种处理方式简化了问题的解决方案,因为它假设所有的操作次数可以自由地用于任一数组的任一位置。然而,这种策略可能不总是最优的,尤其是在实际应用中如果修改`nums1`和`nums2`的成本或影响不同,或者存在某些额外的约束条件时。在这种情况下,可能需要更精细的策略来区分和优化每个数组的修改次数的使用。

相关问题