Problem Statement in English
You’re given an array of integers nums. You have to return an array res where res[i] is the sum of |i - j| between i and all other j such that nums[i] == nums[j].
Approach
Looking at the constraints we can see that a quadratic solution won’t work. We need something better.
In order to make this efficient we’re going to have to open the mod. This gives us the following:
|i - j| = i - jifi > j|i - j| = j - iifi < j
Now we can group the indices of the same values together. Time to do some prefix sums.
To calculate these sums in O(1) time for each i, you pre-calculate the prefix sums of the indices for each unique value.
For a group of k indices, let S be the total sum of all indices in that group. Let P be the prefix sum of indices up to the current index i (including i), and let count be the number of indices processed so far.
The formula for arr[i] becomes:
• Left side sum: (count * i) - P
• Right side sum: (S - P) - ((k - count) * i)
Final arr[i] = Left side sum + Right side sum
And we’re done!
Solution in Python
class Solution:
def distance(self, nums: List[int]) -> List[int]:
hm = defaultdict(list)
for i, v in enumerate(nums):
hm[v].append(i)
res = [0] * len(nums)
for values in hm.values():
N = len(values)
if N <= 1:
continue
s = sum(values)
curr = 0
temp = [0] * N
for i, index in enumerate(values):
curr += index
pre = (index * (i + 1)) - curr
post = (s - curr) - ((N - (i + 1)) * index)
res[index] = pre + post
return res
Complexity
Time: $O(n)$
Since we traverse the array a constant number of times.Space: $O(n)$
Since we store the hashmap and the result array.
Mistakes I Made
I had to look this one up :(
And we are done.