力扣1685 & 2615 前缀和
前缀和使用
给你一个非递减有序整数数组nums,请你建立并返回一个整数数组 result,它跟 nums 长度相同,且result[i] 等于 nums[i] 与数组中所有其他元素差的绝对值之和。换句话说, result[i] 等于 sum(|nums[i]-nums[j]|) ,其中 0 <= j < nums.length 且 j != i (下标从 0 开始)。
示例 1:
输入:nums = [2,3,5]
输出:[4,3,5]
解释:假设数组下标从 0 开始,那么
result[0] = |2-2| + |2-3| + |2-5| = 0 + 1 + 3 = 4,
result[1] = |3-2| + |3-3| + |3-5| = 1 + 0 + 2 = 3,
result[2] = |5-2| + |5-3| + |5-5| = 3 + 2 + 0 = 5。
思路:因为数组是有序的, 对数任意一个数nums[i],在数nums[i]左边的数比nums[i]小, 在nums[i]右边的数比nums[i]大,因此, 计算nums[i]和其他数的差绝对值之和可以分割为两部分来进行计算.首先计算前缀和数组prefixSum[], prefixSum[i]表示前i个数之和.
对于nums[i]的左半部分, nums[i]与其他数的差绝对值之和可计算为:
sumOfLeftDifferences = (i+1)*nums[i]-prefixSum[i];
对于nums[i]的右半部分, nums[i]与其他数的绝对值之和可计算为:
sumOfRightDifferences = prefixSum[nums.length-1]-prefixSum[i]-nums[i]*(nums.length-1-i);
所以, 当前nums[i]与左右其他数的绝对值之和为:
sumOfDifferences = sumOfLeftDifferences+sumOfRightDifferences;
代码
1 | class Solution { |
时间复杂度:O(n)
给你一个下标从 0 开始的整数数组 nums 。现有一个长度等于 nums.length 的数组 arr 。对于满足 nums[j] == nums[i] 且 j != i 的所有 j ,arr[i] 等于所有 |i - j| 之和。如果不存在这样的 j ,则令 arr[i] 等于 0 。返回数组 arr 。
示例 1:
输入:nums = [1,3,1,1,2]
输出:[5,0,3,4,0]示例 2:
输入:nums = [0,5,3]
输出:[0,0,0]
思路:arr[i]的值就是nums中nums[i] == nums[j] && j != i 的i - j的绝对值的和。暴力循环会超时。想同的数之间是相互影响的,把每种数出现的下标用哈希表存起来,再遍历哈希表,对每个数的出现下标进行求差的绝对值之和,就转化为上一题了。
代码
1 | class Solution { |
时间复杂度:O(n)