Problem overview
The method dropEnds gets a vector<int> named nums and returns a new vector without its first and last numbers. The numbers in between keep their order. The constraints guarantee at least two numbers, and when there are exactly two, the answer is an empty vector.
For [4, 8, 15, 16, 23] the answer is [8, 15, 16]. For [9, 0, 9] it is [0], and for [1, 2] it is [].
Approach
Again this is a slice. Start the copy at index 1, so the first number is skipped. Stop the copy at the place of the last index, which is not included, so the last number is skipped too.
The place of index 1 is nums.begin() + 1. The place of the last index is nums.begin() + nums.size() - 1. Between them, the copy takes indexes 1 to size - 2.
Step by step
- Create a
vector<int>namedmiddlefromnums.begin() + 1andnums.begin() + nums.size() - 1. - Return
middle. With two numbers, the two positions are equal, somiddleis empty: nothing sits between the ends.
The solution in C++
class Solution {
public:
vector<int> dropEnds(vector<int> &nums) {
vector<int> middle(nums.begin() + 1, nums.begin() + nums.size() - 1);
return middle;
}
};
nums.size() is an unsigned number. Here the expression adds it to the position first and subtracts 1 after, and for at least two items the result is the place of the last index. On an empty vector, though, nums.size() - 1 by itself would wrap around to a huge number, so code like this relies on the lesson's promise of at least two numbers.
Running the method on the statement's examples prints these results, in bracket notation:
[8, 15, 16]
[0]
[]
A four-number vector [5, 6, 7, 8] gives [6, 7], and the input vector is unchanged afterwards.
Another way
You can end the slice with nums.end() - 1, the place of the last item. It means the same thing and avoids the size:
vector<int> middle(nums.begin() + 1, nums.end() - 1);
On [1, 2, 3, 4] this gives [2, 3].
Trying more inputs
A longer input shows the pattern: [5, 6, 7, 8] becomes [6, 7], so two numbers are dropped and the count goes from 4 to 2. In general a vector of length L gives a result of length L - 2. Two numbers is the smallest input, and its answer is the empty vector.
Printing the input after the call shows it is unchanged, because the new vector is a copy of the middle range. Negative numbers and repeated numbers need no special care: the method works on positions, never on values.
Complexity
Time is O(n), since the middle numbers are copied. Space is O(n) for the new vector.
Edge cases and common mistakes
- Keeping the last number. Ending the copy at
nums.end()includes the last number. The second position must be the place of the last item, because it is not copied. - Ending one place too early.
nums.begin() + nums.size() - 2would also drop the second-to-last number. - Starting at 0. Starting at
nums.begin()keeps the first number. - Short inputs. Two numbers must give an empty vector, not an error. Both positions are then equal, which is a valid empty range.
