本文涉及的基础知识点
基础数学
LeetCode2121. 相同元素的间隔之和
难度分:1760
令2165,和此题几乎相等。
给你一个下标从 0 开始、由 n 个整数组成的数组 arr 。
arr 中两个元素的 间隔 定义为它们下标之间的 绝对差 。更正式地,arr[i] 和 arr[j] 之间的间隔是 |i - j| 。
返回一个长度为 n 的数组 intervals ,其中 intervals[i] 是 arr[i] 和 arr 中每个相同元素(与 arr[i] 的值相同)的 间隔之和 。
注意:|x| 是 x 的绝对值。
示例 1:
输入:arr = [2,1,3,1,2,3,3]
输出:[4,2,7,2,4,4,5]
解释:
- 下标 0 :另一个 2 在下标 4 ,|0 - 4| = 4
- 下标 1 :另一个 1 在下标 3 ,|1 - 3| = 2
- 下标 2 :另两个 3 在下标 5 和 6 ,|2 - 5| + |2 - 6| = 7
- 下标 3 :另一个 1 在下标 1 ,|3 - 1| = 2
- 下标 4 :另一个 2 在下标 0 ,|4 - 0| = 4
- 下标 5 :另两个 3 在下标 2 和 6 ,|5 - 2| + |5 - 6| = 4
- 下标 6 :另两个 3 在下标 2 和 5 ,|6 - 2| + |6 - 5| = 5
示例 2:
输入:arr = [10,5,10,10]
输出:[5,0,3,4]
解释:
- 下标 0 :另两个 10 在下标 2 和 3 ,|0 - 2| + |0 - 3| = 5
- 下标 1 :只有这一个 5 在数组中,所以到相同元素的间隔之和是 0
- 下标 2 :另两个 10 在下标 0 和 3 ,|2 - 0| + |2 - 3| = 3
- 下标 3 :另两个 10 在下标 0 和 2 ,|3 - 0| + |3 - 2| = 4
提示:
n == arr.length
1 <= n <= 10
1 <= arr[i] <= 10
C++
indexs[i] 记录nums中所有值为i的下标。令 v = indexs[i]。
v[0]的距离各下标的和为: ∑ i : v . s i z e ( ) − 1 ( v [ i ] − v [ 0 ] ) \sum_{i:}^{v.size()-1}(v[i]-v[0]) ∑i:v.size()−1(v[i]−v[0]) v[j]也可以这样计算,但这样做的总时间复杂度是:O(nn)。
可以通过v[i] 计算v[i+1]:
令有n1个下标<i,有n2个下标大于i+1。
n1个下标 的距离增加了: v[i+1]- v[i]
n2个下标的距离减少了: v[i+1]- v[i]
即:v[i+1]的总距离 = v[i]的总距离+ (n1-n2)*( v[i+1]- v[i])
n1 =i n2 = n - i -2
代码
核心代码
class Solution {
public:
vector<long long> getDistances(vector<int>& arr) {
const int N = arr.size();
vector<vector<int>> indexs(100'000 + 1);
for (int i = 0; i < arr.size(); i++) {
indexs[arr[i]].emplace_back(i);
}
vector<long long> ret(arr.size());
for (const auto& v : indexs) {
if (v.empty()) { continue; }
long long cur = accumulate(v.begin(), v.end(), 0LL) - (long long)v.front() * v.size();
ret[v[0]] = cur;
for (int i = 0; i + 1 < v.size(); i++) {
ret[v[i + 1]] = ret[v[i]] + ((long long)i-(v.size() - i - 2 )) * ((long long)v[i + 1] - v[i]);
}
}
return ret;
}
};
单元测试
vector<int> arr;
TEST_METHOD(TestMethod11)
{
arr = { 2, 1, 3, 1, 2, 3, 3 };
auto res = Solution().getDistances(arr);
AssertEx(vector<long long>{4, 2, 7, 2, 4, 4, 5}, res);
}
TEST_METHOD(TestMethod12)
{
arr = { 10,5,10,10 };
auto res = Solution().getDistances(arr);
AssertEx(vector<long long>{5,0,3,4}, res);
}
扩展阅读
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。