Optimize the code · Easy

Speed Up Contains Duplicate

Easy Make it fast Most askedSeen at Amazon, Apple, Adobe

containsDuplicate(nums) returns true if any value appears at least twice in nums, otherwise false.

The version below is correct, and it was fine in tests with ten elements. In production it receives arrays of 100,000 IDs and requests start timing out. Make it fast enough that every case, including the 100,000-element ones, finishes inside the time budget. The answers must not change.

Example 1

Input: nums = [1, 2, 3, 1]
Output: true

Example 2

Input: nums = [1, 2, 3, 4]
Output: false

Constraints

  • 0 <= nums.length <= 100000
  • -10^9 <= nums[i] <= 10^9

The slow code

Every case must finish within 300 ms (budgets are per language in the editor).

/**
 * @param {number[]} nums
 * @return {boolean}
 */
function containsDuplicate(nums) {
  for (let i = 0; i < nums.length; i++) {
    for (let j = i + 1; j < nums.length; j++) {
      if (nums[i] === nums[j]) return true;
    }
  }
  return false;
}

Hints

Hint 1

How many pairs does the nested loop compare for n = 100,000?

Hint 2

What data structure answers "have I seen this value before?" in O(1)?

Make it faster

Loading the editor… (JavaScript is required to run code in your browser.)

Solution and explanation

Show the solution

Time O(n) · Space O(n)

Why it is slow: the nested loop compares every pair, n(n-1)/2 comparisons. For 100,000 elements that is about 5 billion comparisons, seconds even in a fast runtime, and it grows with the square of the input.

The fix: remember what you have seen in a hash set. Each element is checked and inserted once, so the work is O(n): about 100,000 set operations instead of 5 billion comparisons. Sorting first and comparing neighbours (O(n log n), O(1) extra space if you may reorder the input) is the other acceptable answer; mention it when memory is tight.

The interview signal is the reasoning: state the current complexity, estimate the work for the real input size, and name the data structure that removes the inner loop.

Optimized solution

function containsDuplicate(nums) {
  const seen = new Set();
  for (const x of nums) {
    if (seen.has(x)) return true;
    seen.add(x);
  }
  return false;
}

Common mistakes

  • Using array.includes(x) / x in list inside the loop: still O(n^2), just hidden.
  • Building new Set(nums).size !== nums.length is fine, but cannot stop early on the first duplicate.
  • Sorting the caller's array in place without saying so.

Follow-up questions

  • Contains Duplicate II: duplicates at most k indices apart (sliding-window set).
  • The input does not fit in memory: what would you do? (external sort, or hash-partition to disk)