距离和 (数学化简后 前缀和)
问题可能是多样的, 但是核心是一个类似于以下形态的式子:
这个是距离和
相关题目的特征 (个人认为), 做题时候只需要展开后慢慢推导即可qwq...
例如:
输入: 一个 非递减 有序整数数组
num
vector<int> getSumAbsoluteDifferences(vector<int>& nums)
返回一个整数数组
res
, 它跟nums
长度相同, 且res[i]
等于nums[i]
与数组中所有其他元素差的绝对值之和.换句话说,
res[i]
等于sum(|nums[i]-nums[j]|)
, 其中0 <= j < nums.length
且j != i
(下标从 0 开始).
此时得到的式子是:
我们可以将其展开:
由于数组是非递减的, 我们可以把绝对值拆开:
然后去掉括号+移项, 亦有:
即
而对于求解 与 显然我们可以使用前缀和来计算.
故有:
class Solution {
public:
vector<int> getSumAbsoluteDifferences(vector<int>& nums) {
int n = nums.size();
vector<int> sum(n + 1);
for (int i = 0; i < n; ++i)
sum[i + 1] = sum[i] + nums[i];
vector<int> res(n);
for (int i = 0; i < n; ++i) {
res[i] = (sum[n] - sum[i]) - (sum[i] - sum[0])
+ nums[i] * (i - (n - i));
}
return res;
}
};
Tip
为何是 而不是 ?
答: 是换算到索引的, 而这里表示的是个数, 因此使用 即可! (小心不要和前缀和的长度搞混了!)
相关题目
- 本题 1685. 有序数组中差绝对值之和 1496
- 2615. 等值距离和 1793
- 2602. 使数组元素全部相等的最少操作次数 1903
更多可以参考灵神题单: