Start learning free

LESSON 240 OF 675 · SETS

Remove Repeats in TypeScript: Keeping First Copies

Practice Read the full explanation

You get an array of integers nums. Some values may appear more than once.

Return a new array that has each value only once.

Keep the first copy of each value and drop the later ones. The values stay in the order they first appear in nums.

 

Example 1:

Input: nums = [3, 1, 3, 2, 1]
Output: [3, 1, 2]
Explanation: The second 3 and the second 1 are repeats.
They are dropped, and 3, 1 and 2 stay in their order.

Example 2:

Input: nums = [6, 6, 6, 6]
Output: [6]
Explanation: Only the first 6 stays.

Example 3:

Input: nums = [4, 9, 2]
Output: [4, 9, 2]
Explanation: No value repeats, so every number stays.

 

Constraints:

  • nums has at least one number.
  • Every number is between -109 and 109.
STEP 1 OF 7
    Ctrl + Enter to check

    TYPESCRIPT · SETS

    Remove Repeats in TypeScript, explained

    Problem overview

    The method removeRepeats receives an array of integers, nums, and returns a new array in which each value appears once. The first copy of each value stays, later copies are dropped, and the values keep the order in which they first appeared. The input has at least one number, each between -1,000,000,000 and 1,000,000,000.

    For [3, 1, 3, 2, 1] the result is [3, 1, 2]: the second 3 and the second 1 are repeats. For [6, 6, 6, 6] the result is [6], and for [4, 9, 2] nothing repeats, so every number stays.

    Approach: remember what you have seen

    Read the numbers from left to right. For each one, ask whether it has appeared before. If not, it is a first copy: put it in the result and remember it. If so, skip it. Reading in order is what guarantees that the kept copy is the first one and that the order is preserved.

    The question "have I seen this value?" is what a Set answers quickly. An array's includes would work too, but it looks at the values one by one, so the set is the better tool.

    Step by step

    1. Create seen, an empty Set<number>, for the values met so far.
    2. Create result, an empty number[], for the values to return.
    3. Loop over nums with for...of, from first to last.
    4. Test !seen.has(num). The ! turns the answer around, so the test is true only for a value that is new.
    5. Push num onto result. Adding at the end keeps the order of first appearance.
    6. Add num to seen, so that its later copies are skipped.
    7. Return result after the loop. Returning inside the loop would send back only the first value.

    The solution in TypeScript

    class Solution {
        removeRepeats(nums: number[]): number[] {
            let seen: Set<number> = new Set();
            let result: number[] = [];
            for (let num of nums) {
                if (!seen.has(num)) {
                    result.push(num);
                    seen.add(num);
                }
            }
            return result;
        }
    }
    

    Some details:

    • new Set() with a type annotation. The annotation Set<number> on the variable tells TypeScript what the set holds. Types are erased when the code compiles, so the set itself holds whatever you add.
    • A shorter way. [...new Set(nums)] also drops repeats and keeps first-appearance order, because a set remembers insertion order. For [3, 1, 3, 2, 1] it gives [3,1,2]. The lesson builds the longer version so you see each step.
    • Negative numbers and large values are ordinary values for a set. [-5, 0, -5, 1000000000, 1000000000] gives [-5,0,1000000000].

    Edge cases and common mistakes

    • Adding to seen before the test. If seen.add(num) comes before the if, the value is always already there, the test is never true, and the result stays empty.
    • Sorting first. Sorting would bring equal values together, but it destroys the order the task wants to keep.
    • Returning the set. The method returns an array, so the set is only a helper.
    • Equal values that are not next to each other. The set remembers every value met so far, not just the previous one, so in [3, 1, 3, 2, 1] the second 3 is caught even though a 1 sits between the two 3s. Comparing each number only with its neighbour would miss it.
    • Single value. An array with one number returns an array with that number.

    Testing

    • [3, 1, 3, 2, 1] gives [3, 1, 2].
    • [6, 6, 6, 6] gives [6].
    • [4, 9, 2] gives [4, 9, 2].
    Keep going with TypeScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free