Problem overview
The method firstN receives a list of integers nums and a number n, and returns a new list with the first n numbers of nums, in the same order. The tests guarantee that n is between 0 and the length of nums, and when n is 0 the result is an empty list.
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 [2, 4] and n = 2 every number is kept.
Approach
This is exactly what subList(from, to) does. It returns the items from index from up to, but not including, index to, so nums.subList(0, n) holds the items at indexes 0 to n - 1: the first n items. When n is 0 the range is empty, so the edge case needs no special code.
There is one catch. subList does not copy anything: it is a window onto nums, so changing the window changes nums. The task asks for a new list, so the window is copied into a new ArrayList.
Step by step
- Take the window with
nums.subList(0, n). - Copy it by passing it to
new ArrayList<>(...), and keep the copy in aList<Integer>namedresult. - Return
result.
The solution in Java
class Solution {
public List<Integer> firstN(List<Integer> nums, int n) {
List<Integer> result = new ArrayList<>(nums.subList(0, n));
return result;
}
}
Details worth knowing:
- The variable is declared as
List<Integer>while the object is anArrayList. That is the usual style: the type says what you can do, and the right-hand side says what you built. - The diamond
<>lets Java work outIntegerfrom the left side. - Because the copy is independent, adding to the result later does not touch
nums. Withnums = [3, 8, 1, 9, 4]andn = 3, adding 99 to the result gives3 8 1 99andnumsstill holds3 8 1 9 4.
Edge cases and common mistakes
- Returning the view.
return nums.subList(0, n);compiles, but the result is tied tonums. Always copy when the task asks for a new list. - Using
n - 1as the end. The end index is excluded, sosubList(0, n - 1)returns one number too few. - n larger than the list. The lesson's tests never do this, but
subList(0, 3)on a two-item list throws anIndexOutOfBoundsException(the message istoIndex = 3). - n = 0.
subList(0, 0)is a valid empty range, so noifis needed.
Why subList and not a loop
A loop that adds nums.get(i) to a new list for i from 0 to n - 1 gives the same answer, and it is a good exercise. The library call says the same thing in one line and states the rule in its own signature: from index 0, up to but not including n. When n equals the length of nums, the end index is nums.size(), which subList accepts, so a full copy needs no special case either.
Tracing the examples
[3, 8, 1, 9, 4]withn = 3:subList(0, 3)covers the indexes 0, 1 and 2, which hold 3, 8 and 1. Index 3 holds the 9, and it is outside the window.[5, 6, 7]withn = 0:subList(0, 0)starts and ends at the same place, so the window is empty and the copy is an empty list.[2, 4]withn = 2:subList(0, 2)ends atsize(), so the window is the whole list.
Testing
Inputs and the output of the solution, printed as numbers separated by spaces:
[3, 8, 1, 9, 4],n = 3gives3 8 1.[5, 6, 7],n = 0gives an empty list.[2, 4],n = 2gives2 4.
