Problem overview
firstN receives an array of integers nums and a number n. It returns a new array with the first n numbers, in the same order. When n is 0 the result is an empty array, and n is never larger than the length of nums.
For nums = [3, 8, 1, 9, 4] and n = 3 the answer is [3, 8, 1]: the 9 and the 4 are left out. For [5, 6, 7] and n = 0 it is [], and for [2, 4] and n = 2 every number is kept.
Approach
This is exactly what slice does. nums.slice(0, n) copies the items from index 0 up to, but not including, index n. Those are the items at indexes 0 to n - 1, which is n numbers. No loop and no special case for 0 is needed, because slice(0, 0) is an empty array.
Step by step
- Copy the first n numbers. Call
slicefrom 0 tonand keep the copy in a constant namedresultof typenumber[]. - Return it. The copy is a new array, so
numsitself stays as it was.
The solution in TypeScript
class Solution {
firstN(nums: number[], n: number): number[] {
const result: number[] = nums.slice(0, n);
return result;
}
}
Running it on the three examples gives:
[ 3, 8, 1 ] [] [ 2, 4 ]
The type annotation number[] is for the compiler and the reader only. TypeScript erases it when it compiles to JavaScript, so it checks nothing while the program runs.
Tracing the first example
With nums = [3, 8, 1, 9, 4] and n = 3, the indexes are 0 to 4. The call slice(0, 3) copies the items at indexes 0, 1 and 2, which are 3, 8 and 1, and stops before index 3. The items at indexes 3 and 4, the 9 and the 4, are never copied. The length of the result is always the end minus the start, here 3 - 0 = 3, which is why the end index can simply be n.
Another way: a loop
The same result can be built by hand. Start with an empty array and push the numbers at indexes 0 to n - 1:
const result: number[] = [];
for (let i = 0; i < n; i++) {
result.push(nums[i]);
}
On the three examples it gives the same [ 3, 8, 1 ] [] [ 2, 4 ]. When n is 0 the loop body never runs, so the empty array comes back untouched. This works, but slice says the same in one line and cannot go wrong with the loop bounds, which is why the lesson uses it.
Edge cases and common mistakes
- The end index is excluded. Using
n - 1as the end would return one number too few. - n equal to 0. The result is an empty array, with no extra code.
- n equal to the length.
slice(0, nums.length)copies everything, so[2, 4]stays[2, 4]. - Changing the copy does not change the input. After
result.push(99)on the copy of[3, 8, 1, 9, 4]withn = 3, the original still holds its five numbers. That would not be true if the function returnednumsitself. - Don't confuse it with
splice.splice(0, n)also returns the firstnnumbers, but it removes them fromnums.
Testing
Try a single number and a negative one: firstN([7], 1) returns [ 7 ], and firstN([-5, 0, 5, 10], 1) returns [ -5 ]. The numbers' signs do not matter, because slice only looks at positions.
