运用滑动窗口,优化LeetCode有序数组差值之和Java实现!
2023-09-26 22:11:54
LeetCode:有序数组中差绝对值之和Java 题解
欢迎来到 LeetCode 每日一题栏目!今天我们继续来解题。
题目
给你一个 非递减 有序整数数组 nums 。 请你建立并返回一个整数数组 result,它跟 nums 长度相同。 其中每个 result[i] 的值定义为 nums[i] 与原数组中所有其他元素的绝对值之和。
比方说我们给出的数组为 nums = [4, 2, 1, 3],那么我们返回的 result = [49, 36, 30, 36]。
我们再来看一个例子,nums = [1, 4, 4, 4],则 result = [8, 0, 0, 0]。
参考实现(Java)
class Solution {
/**
* 给定一个非递减有序整数数组nums,请你建立并返回一个整数数组result,
* 其中每个result[i]的值定义为nums[i]与原数组中所有其他元素的绝对值之和。
* @param nums 给定的数组
* @return 计算出的结果数组
*/
public int[] getSumAbsoluteDifferences(int[] nums) {
int length = nums.length;
int[] result = new int[length];
// 计算数组和
int sum = 0;
for (int num : nums) {
sum += num;
}
// 计算前缀和数组
int[] prefixSum = new int[length];
prefixSum[0] = nums[0];
for (int i = 1; i < length; i++) {
prefixSum[i] = prefixSum[i - 1] + nums[i];
}
// 计算后缀和数组
int[] suffixSum = new int[length];
suffixSum[length - 1] = nums[length - 1];
for (int i = length - 2; i >= 0; i--) {
suffixSum[i] = suffixSum[i + 1] + nums[i];
}
// 计算结果数组
for (int i = 0; i < length; i++) {
result[i] = sum - 2 * prefixSum[i] + i * nums[i] - (length - i - 1) * nums[i];
}
return result;
}
}
算法思路
1. 前缀和数组
预先计算出前缀和数组,其中第 i 个元素的值为 nums[0] + nums[1] + ... + nums[i]。这样,我们可以通过 O(1) 的时间复杂度查询 nums[0] 到 nums[i] 的和。
2. 后缀和数组
预先计算出后缀和数组,其中第 i 个元素的值为 nums[i] + nums[i+1] + ... + nums[length-1]。这样,我们可以通过 O(1) 的时间复杂度查询 nums[i] 到 nums[length-1] 的和。
3. 计算结果数组
对于每个元素 nums[i],我们需要计算它与其他所有元素的绝对值之和。我们可以使用前缀和数组和后缀和数组来快速计算出这个值。具体地,对于每个元素 nums[i],我们可以通过以下公式计算出它与其他所有元素的绝对值之和:
sum - 2 * prefixSum[i] + i * nums[i] - (length - i - 1) * nums[i]
其中,sum 是数组 nums 的和,prefixSum[i] 是前缀和数组的第 i 个元素,length 是数组 nums 的长度。
总结
LeetCode 每日一题栏目到此结束,希望大家能通过本文学到一些新的知识和算法。如果您有任何问题或建议,欢迎在评论区留言。