Problem overview
The function dropEnds receives a slice of integers, nums, and returns a slice with every number except the first and the last. The numbers in between keep their order. The constraints say nums has at least two numbers.
For [4, 8, 15, 16, 23] the 4 and the 23 are the ends, so the answer is [8 15 16]. For [9, 0, 9] both 9s are ends and only the 0 remains. For [1, 2] nothing is between the ends, so the result is empty.
Approach
A slice expression nums[i:j] takes the items from index i up to, but not including, index j. Starting at index 1 skips the first number. The last index of the slice is len(nums)-1, and because the end index is not included, ending there skips the last number too. Go has no negative indexes, so the end is written with len.
It helps to count with the first example. [4, 8, 15, 16, 23] has 5 numbers, so len(nums) is 5 and the last index is 4. The slice nums[1:4] holds the items at indexes 1, 2 and 3, which are 8, 15 and 16. In general, nums[1:len(nums)-1] has len(nums) - 2 items, whatever the length of nums.
A loop version also works: start from an empty slice and append nums[i] for i from 1 while i < len(nums)-1. It gives the same answers, with more lines to write.
Step by step
- Slice
numsfrom index 1 up tolen(nums)-1and store it inmiddle, declared with:=. - Return
middle.
The solution in Go
func dropEnds(nums []int) []int {
middle := nums[1:len(nums)-1]
return middle
}
Like every slice of a slice, middle shares its items with nums instead of copying them. The function doesn't change anything, so that is fine here.
Because middle shares memory with nums, setting middle[0] = 99 on the first example changes nums too, to [4 99 15 16 23]. If you ever need to edit the middle without touching the original, take a copy with slices.Clone.
Testing
Running the function on the statement's examples prints:
| nums | result |
|---|---|
[4 8 15 16 23] | [8 15 16] |
[9 0 9] | [0] |
[1 2] | [] |
For two numbers the slice is nums[1:1], which has length 0. An empty range is legal in Go as long as the start doesn't exceed the end.
Edge cases and common mistakes
The lesson's tests include the smallest allowed input, two numbers, where the answer is empty. The same code handles it with no if, because a slice expression whose start equals its end is valid. The result is an empty slice with length 0, which prints as [].
- Ending at
len(nums).nums[1:len(nums)]drops only the first number. The last one stays, because the end index is the first item left out. - Ending at
len(nums)-2. That also drops the second-to-last number. For[4 8 15 16 23]you would get[8 15]. - A one-item slice. The constraints guarantee at least two numbers. For a single number,
nums[1:0]has a start larger than its end and panics withslice bounds out of range [1:0]. An empty input would panic too, so a function used on unchecked data should testlen(nums) < 2first.
