难点在于:给出一个递增数组,在O(n) 的时间内得到所有元素跟其他元素之间的绝对值的和。
解法:分组+前缀和
1.先用哈希表记录每个值,以及这个值对应的所有下标。
2.前缀和+后缀和
前、后缀和分别表示该位置与前面(后面)所有位置的差绝对值之和。
sum1为前缀和数组。
sum1[0] = 0;
sum1[i] = sum1[i - 1] + (nums[i] - nums[i - 1]) * i;
sum2为后缀和数组
计算方式同理。
i位置与其他所有值的差值和:sum1[i]+sum2[i];
class Solution {
public:
vector<long long> getDistances(vector<int>& arr) {
int n = arr.size();
vector<long long> ans(n);
unordered_map<int, vector<int>> ump;
for (int i = 0; i < n; ++i) {
ump[arr[i]].push_back(i);
}
for (auto& each : ump) {
long long tmp = 0;
int m = each.second.size();
vector<long long> sum1(m);
vector<long long> sum2(m);
sum1[0] = 0; sum2[m - 1] = 0;
for (int i = 1; i < m; ++i) {
sum1[i] = sum1[i - 1] + i * (each.second[i] - each.second[i - 1]);
}
for (int i = m - 2; i >= 0; --i) {
sum2[i] = sum2[i + 1] + (m - i - 1) * (each.second[i + 1] - each.second[i]);
}
for (int i = 0; i < m; ++i) {
ans[each.second[i]] = sum1[i] + sum2[i];
}
}
return ans;
}
};