class Solution {
public:
vector<long long> getDistances(vector<int>& arr) {
}
};
2121. 相同元素的间隔之和
给你一个下标从 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 <= 105
1 <= arr[i] <= 105
原站题解
golang 解法, 执行用时: 192 ms, 内存消耗: 26.8 MB, 提交时间: 2023-06-16 17:55:30
func getDistances(arr []int) []int64 { pos := map[int][]int{} for i, v := range arr { pos[v] = append(pos[v], i) // 记录相同元素的位置 } ans := make([]int64, len(arr)) for _, p := range pos { // 遍历每个组 sum := int64(0) for _, i := range p { sum += int64(i - p[0]) // 该组第一个元素的间隔和 } ans[p[0]] = sum for i, n := 1, len(p); i < n; i++ { sum += int64(2*i-n) * int64(p[i]-p[i-1]) // 计算该组下一个元素的间隔和(考虑变化量) ans[p[i]] = sum } } return ans }
cpp 解法, 执行用时: 288 ms, 内存消耗: 115.8 MB, 提交时间: 2023-06-16 17:55:02
class Solution { public: vector<long long> getDistances(vector<int> &arr) { unordered_map<int, vector<int>> pos; for (int i = 0; i < arr.size(); ++i) pos[arr[i]].push_back(i); // 记录相同元素的位置 vector<long long> ans(arr.size()); for (auto &[_, p] : pos) { // 遍历每个组 long sum = 0L; for (int i : p) sum += i - p[0]; // 该组第一个元素的间隔和 ans[p[0]] = sum; for (int i = 1, n = p.size(); i < n; ++i) ans[p[i]] = sum += (2L * i - n) * (p[i] - p[i - 1]); // 计算该组下一个元素的间隔和(考虑变化量) } return ans; } };
java 解法, 执行用时: 46 ms, 内存消耗: 83.8 MB, 提交时间: 2023-06-16 17:54:49
class Solution { public long[] getDistances(int[] arr) { var pos = new HashMap<Integer, List<Integer>>(); for (var i = 0; i < arr.length; i++) pos.computeIfAbsent(arr[i], k -> new ArrayList<>()).add(i); // 记录相同元素的位置 var ans = new long[arr.length]; for (var p : pos.values()) { var sum = 0L; for (var i : p) sum += i - p.get(0); // 该组第一个元素的间隔和 ans[p.get(0)] = sum; for (int i = 1, n = p.size(); i < n; i++) ans[p.get(i)] = sum += (2L * i - n) * (p.get(i) - p.get(i - 1)); // 计算该组下一个元素的间隔和(考虑变化量) } return ans; } }
python3 解法, 执行用时: 540 ms, 内存消耗: 50.8 MB, 提交时间: 2023-06-16 17:54:36
# 考虑间隔和的变化量 class Solution: def getDistances(self, arr: List[int]) -> List[int]: pos = defaultdict(list) for i, v in enumerate(arr): pos[v].append(i) # 记录相同元素的位置 ans = [0] * len(arr) for p in pos.values(): # 遍历每个组 ans[p[0]] = s = sum(i - p[0] for i in p) # 该组第一个元素的间隔和 n = len(p) for i in range(1, n): s += (2 * i - n) * (p[i] - p[i - 1]) # 计算该组下一个元素的间隔和(考虑变化量) ans[p[i]] = s return ans