Problem overview
The function firstN gets a MutableList<Int> called nums and a number n. It returns the first n numbers, in the same order. When n is 0 the result is empty, and when n equals the length of nums every number is kept. The constraints keep n between 0 and the list's length.
For nums = [3, 8, 1, 9, 4] and n = 3, the answer holds 3, 8 and 1; the 9 and the 4 are left out. For [5, 6, 7] and n = 0 it is empty, and for [2, 4] with n = 2 it is [2, 4].
Approach
Think of the call as subList(from, to) with from fixed at 0. Only the end changes with n.
Indexes in Kotlin start at 0, so the first n numbers sit at indexes 0 to n - 1. subList(from, to) takes the items from from up to, but not including, to. With from = 0 and to = n that is exactly the range we want, and when n is 0 the range is empty, so no special case is needed.
Step by step
- Take the slice. Call
subListonnumswith 0 andnand keep it in avalnamedresult. - Return it.
subListon aMutableListgives aMutableList, which is the type the function returns.
The solution in Kotlin
class Solution {
fun firstN(nums: MutableList<Int>, n: Int): MutableList<Int> {
val result = nums.subList(0, n)
return result
}
}
Running it on the three examples gives these results (the tests print a list as its values separated by spaces):
3 8 1
(empty line)
2 4
One detail worth knowing: subList returns a view of nums, not a new list. Reading it is fine. But if you change an item of the result, the matching item of nums changes too: after val f = firstN(orig, 2) and f[0] = 99, orig starts with 99. If you need a separate list, write nums.subList(0, n).toMutableList(). The lesson's tests only read the result, so the plain version is enough.
Another way
Kotlin also has take(n), which returns a new list with the first n items. Add toMutableList() to get the MutableList the function must return:
fun firstN(nums: MutableList<Int>, n: Int): MutableList<Int> = nums.take(n).toMutableList()
It gives [3, 8, 1] for the first example and [] for the second. Unlike subList, it copies the items, and it doesn't throw when n is larger than the list: it just returns the whole list. The lesson's steps use subList, so that is the version to submit.
How the indexes line up
For [3, 8, 1, 9, 4] the items sit at indexes 0 to 4. With n = 3 the slice runs from index 0 up to index 3, so it takes the items at 0, 1 and 2 and stops before the 9. The length of a slice is always to - from, here 3 - 0 = 3, which is a handy way to check you picked the right end index.
Edge cases and common mistakes
n = 0.subList(0, 0)is empty. Noifis needed.nequal to the size.subList(0, nums.size)is the whole list.- Using
n - 1as the end. The end index is excluded, sosubList(0, n - 1)returns one number too few. nbigger than the size. The constraints rule it out, butsubListwould throw anIndexOutOfBoundsExceptionrather than return the whole list.
Where this idea is used
Slicing off the first n items is a basic list skill: showing the top three results, keeping the first page of a longer list, or splitting a list in two at position n with subList(0, n) and subList(n, nums.size). The two halves meet at index n without overlap or gap, and each half is empty when n is 0 or the full length.
Testing
[3, 8, 1, 9, 4],n = 3gives3 8 1.[5, 6, 7],n = 0gives an empty list.[2, 4],n = 2gives2 4.
