How to find the minimum distance between two numbers in an array with JavaScript

1 Answer

0 votes
/**
 * Utility methods for finding distances between values in arrays.
 */
class ArrayDistance {
    /**
     * Finds the minimum distance between two target values in an array.
     *
     * Example:
     * [2, 3, 7, 3, 3, 4, 8, 8, 8, 11, 9, 1, 3]
     *
     * Targets:
     * 3 and 8
     *
     * Result:
     * 2
     *
     * @param {number[]} numbers - The input array.
     * @param {number} target1 - The first target value.
     * @param {number} target2 - The second target value.
     * @returns {number}
     * Returns the minimum distance between the targets,
     * or -1 if no valid pair exists.
     * @throws {TypeError} If numbers is not an array.
     */
    static findMinimumDistance(numbers, target1, target2) {
        if (!Array.isArray(numbers)) {
            throw new TypeError("numbers must be an array.");
        }

        // Special case: both targets are the same value.
        if (target1 === target2) {
            return this.findMinimumDistanceBetweenDuplicates(
                numbers,
                target1
            );
        }

        let lastSeenIndex = -1;
        let minimumDistance = Number.MAX_SAFE_INTEGER;

        for (let currentIndex = 0; currentIndex < numbers.length; currentIndex++) {
            const currentValue = numbers[currentIndex];

            // Ignore values that are not relevant.
            if (currentValue !== target1 && currentValue !== target2) {
                continue;
            }

            /*
             * If we've previously seen one target value and
             * the current value is the other target value,
             * update the minimum distance.
             */
            if (
                lastSeenIndex >= 0 &&
                currentValue !== numbers[lastSeenIndex]
            ) {
                const distance = currentIndex - lastSeenIndex;

                minimumDistance = Math.min(
                    minimumDistance,
                    distance
                );
            }

            // Store the most recent occurrence.
            lastSeenIndex = currentIndex;
        }

        return minimumDistance === Number.MAX_SAFE_INTEGER
            ? -1
            : minimumDistance;
    }

    /**
     * Finds the minimum distance between consecutive occurrences
     * of the same value.
     *
     * @param {number[]} numbers - The input array.
     * @param {number} target - The target value.
     * @returns {number}
     * Returns the minimum distance or -1 if the value appears
     * fewer than two times.
     */
    static findMinimumDistanceBetweenDuplicates(numbers, target) {
        let previousIndex = -1;
        let minimumDistance = Number.MAX_SAFE_INTEGER;

        for (let i = 0; i < numbers.length; i++) {
            if (numbers[i] !== target) {
                continue;
            }

            if (previousIndex >= 0) {
                const distance = i - previousIndex;

                minimumDistance = Math.min(
                    minimumDistance,
                    distance
                );
            }

            previousIndex = i;
        }

        return minimumDistance === Number.MAX_SAFE_INTEGER
            ? -1
            : minimumDistance;
    }
}

/*
 * Example usage
 */
const numbers = [2, 3, 7, 3, 3, 4, 8, 8, 8, 11, 9, 1, 3];

const result = ArrayDistance.findMinimumDistance(numbers, 3, 8);

console.log(
    result >= 0
        ? `Minimum distance between 3 and 8: ${result}`
        : "No valid pair found."
);


/*
run:

Minimum distance between 3 and 8: 2

*/

 



answered Aug 24, 2022 by avibootz
edited Oct 21 by avibootz
...