You are given a 0-indexed integer array nums. There exists an array
arr of length nums.length, where arr[i] is the sum of |i - j| over all
j such that nums[j] == nums[i] and j != i. If there is no such j, set
arr[i] to be 0.
Input: nums =[1,3,1,1,2]Output: [5,0,3,4,0]Explanation:
When i =0, nums[0]== nums[2] and nums[0]== nums[3]. Therefore, arr[0]=|0-2|+|0-3|=5.When i =1, arr[1]=0 because there is no other index with value 3.When i =2, nums[2]== nums[0] and nums[2]== nums[3]. Therefore, arr[2]=|2-0|+|2-3|=3.When i =3, nums[3]== nums[0] and nums[3]== nums[2]. Therefore, arr[3]=|3-0|+|3-2|=4.When i =4, arr[4]=0 because there is no other index with value 2.
For each value, collect all its indices. For each index, the sum of distances to all other indices with the same value can be computed efficiently using prefix sums. This avoids brute-force and leverages the sorted order of indices.
classSolution {
public: vector<longlong> distance(vector<int>& nums) {
int n = nums.size();
unordered_map<int, vector<int>> pos;
for (int i =0; i < n; ++i) pos[nums[i]].push_back(i);
vector<longlong> ans(n);
for (auto& [val, idxs] : pos) {
int m = idxs.size();
vector<longlong> pre(m+1);
for (int i =0; i < m; ++i) pre[i+1] = pre[i] + idxs[i];
for (int i =0; i < m; ++i) {
longlong left =1LL* idxs[i] * i - pre[i];
longlong right = (pre[m] - pre[i+1]) -1LL* idxs[i] * (m - i -1);
ans[idxs[i]] = left + right;
}
}
return ans;
}
};
classSolution {
publiclong[]distance(int[] nums) {
int n = nums.length;
Map<Integer, List<Integer>> pos =new HashMap<>();
for (int i = 0; i < n; i++) pos.computeIfAbsent(nums[i], k ->new ArrayList<>()).add(i);
long[] ans =newlong[n];
for (List<Integer> idxs : pos.values()) {
int m = idxs.size();
long[] pre =newlong[m+1];
for (int i = 0; i < m; i++) pre[i+1]= pre[i]+ idxs.get(i);
for (int i = 0; i < m; i++) {
long left = (long)idxs.get(i) * i - pre[i];
long right = (pre[m]- pre[i+1]) - (long)idxs.get(i) * (m - i - 1);
ans[idxs.get(i)]= left + right;
}
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
fundistance(nums: IntArray): LongArray {
val n = nums.size
val pos = mutableMapOf<Int, MutableList<Int>>()
for (i in nums.indices) pos.getOrPut(nums[i]) { mutableListOf() }.add(i)
val ans = LongArray(n)
for (idxs in pos.values) {
val m = idxs.size
val pre = LongArray(m+1)
for (i in0 until m) pre[i+1] = pre[i] + idxs[i]
for (i in0 until m) {
val left = idxs[i].toLong() * i - pre[i]
val right = (pre[m] - pre[i+1]) - idxs[i].toLong() * (m - i - 1)
ans[idxs[i]] = left + right
}
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution:
defdistance(self, nums: list[int]) -> list[int]:
from collections import defaultdict
n = len(nums)
pos = defaultdict(list)
for i, v in enumerate(nums):
pos[v].append(i)
ans = [0] * n
for idxs in pos.values():
m = len(idxs)
pre = [0] * (m +1)
for i in range(m):
pre[i+1] = pre[i] + idxs[i]
for i in range(m):
left = idxs[i] * i - pre[i]
right = (pre[m] - pre[i+1]) - idxs[i] * (m - i -1)
ans[idxs[i]] = left + right
return ans
impl Solution {
pubfndistance(nums: Vec<i32>) -> Vec<i64> {
use std::collections::HashMap;
let n = nums.len();
letmut pos: HashMap<i32, Vec<usize>>= HashMap::new();
for (i, &v) in nums.iter().enumerate() {
pos.entry(v).or_default().push(i);
}
letmut ans =vec![0i64; n];
for idxs in pos.values() {
let m = idxs.len();
letmut pre =vec![0i64; m+1];
for i in0..m {
pre[i+1] = pre[i] + idxs[i] asi64;
}
for i in0..m {
let left = idxs[i] asi64* i asi64- pre[i];
let right = (pre[m] - pre[i+1]) - idxs[i] asi64* (m asi64- i asi64-1);
ans[idxs[i]] = left + right;
}
}
ans
}
}