You can improve the function's time complexity at the expense of memory by tracking the duplicates in a separate set. This will reduce the number of iterations by the number of unique items in the input array, and increase the memory need by the same number.


<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    function countDuplicates(original) {
      const uniqueItems = new Set();
      const duplicates = new Set();
      for (const value of original) {
        if (uniqueItems.has(value)) {
          duplicates.add(value);
        } else {
          uniqueItems.add(value);
        }
      }
      return duplicates.size;
    }


    /* Test code not related to solution */
    function test(name, func, data, result) {
      const output =  `${name} [${data.join(", ")}] : `;
      console.log(output + (func(data) === result ? "passed" : "failed")); 
    }


    test("1 duplicate ", countDuplicates, [9, 11, 12, 2, 7, 4, 2], 1);
    test("1 duplicate ", countDuplicates, [6, 6, 6], 1);
    test("2 duplicates ", countDuplicates, [0, 1, 4, 2, 7, 4, 2], 2);
    test("3 duplicates ", countDuplicates, [0, 1, 4, 2, 7, 4, 2, 0], 3);
    test("No duplicates ", countDuplicates, [0, 1, 4, 2, 7, 5, 8, 9], 0);

<!-- end snippet -->



You can further reduce the memory complexity by increasing the logic in the loop, this will slow down the function by not increase its time complexity.



<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    function countDuplicates(original) {
      var maxSize = 0;
      const uniqueItems = new Set();
      const duplicates = new Set();
      for (const value of original) {
        if (uniqueItems.has(value)) {
          duplicates.add(value);
          uniqueItems.delete(value);

        } else {
          uniqueItems.add(value);
        }
        maxSize = Math.max(maxSize, duplicates.size + uniqueItems.size);
      }
log(maxSize)
      return duplicates.size;
    }


    /* Test code not related to solution */
    function test(name, func, data, result) {
      const output =  `${name} [${data.join(", ")}] : `;
      console.log(output + (func(data) === result ? "passed" : "failed")); 
    }


    test("1 duplicate ", countDuplicates, [9, 11, 12, 2, 7, 4, 2], 1);
    test("1 duplicate ", countDuplicates, [6, 6, 6], 1);
    test("2 duplicates ", countDuplicates, [0, 1, 4, 2, 7, 4, 2], 2);
    test("3 duplicates ", countDuplicates, [0, 1, 4, 2, 7, 4, 2, 0], 3);
    test("No duplicates ", countDuplicates, [0, 1, 4, 2, 7, 5, 8, 9], 0);

<!-- end snippet -->