Description
You are given an integer array nums.
A tuple (i, j, k) of 3 distinct indices is good if nums[i] == nums[j] == nums[k].
The distance of a good tuple is abs(i - j) + abs(j - k) + abs(k - i), where abs(x) denotes the absolute value of x.
Return an integer denoting the minimum possible distance of a good tuple. If no good tuples exist, return -1.
Example 1:
Input: nums = [1,2,1,1,3]
Output: 6
Explanation:
The minimum distance is achieved by the good tuple (0, 2, 3).
(0, 2, 3) is a good tuple because nums[0] == nums[2] == nums[3] == 1. Its distance is abs(0 - 2) + abs(2 - 3) + abs(3 - 0) = 2 + 1 + 3 = 6.
Example 2:
Input: nums = [1,1,2,3,2,1,2]
Output: 8
Explanation:
The minimum distance is achieved by the good tuple (2, 4, 6).
(2, 4, 6) is a good tuple because nums[2] == nums[4] == nums[6] == 2. Its distance is abs(2 - 4) + abs(4 - 6) + abs(6 - 2) = 2 + 2 + 4 = 8.
Example 3:
Input: nums = [1]
Output: -1
Explanation:
There are no good tuples. Therefore, the answer is -1.
Constraints:
1 <= n == nums.length <= 1051 <= nums[i] <= n
Solutions
This variant efficiently finds the minimum distance between identical elements by storing exactly two positions [older, newer] for each number. As it iterates through the array, it checks if there's a previous occurrence (arr[0] !== -1) and calculates the distance between that position and the current index. The stored positions are then updated—shifting the newer position to older and storing the current index as newer—allowing the algorithm to track consecutive occurrences. It returns twice the minimum distance found, or -1 if no duplicate exists.
/**
* @param {number[]} nums
* @return {number}
*/
var minimumDistance = function(nums) {
const map = new Map();
let res = Infinity;
for (let i = 0; i < nums.length; i++) {
const arr = map.get(nums[i]) || [-1, -1];
if (arr[1] === -1) {
map.set(nums[i], arr);
}
if (arr[0] !== -1) {
res = Math.min(res, i - arr[0]);
}
arr[0] = arr[1];
arr[1] = i;
}
if (res === Infinity) {
return -1;
}
return 2 * res;
};