Start learning free

LESSON 122 OF 677 · ARRAYS - CHALLENGES

Drop the Ends in Scala

Practice Read the full explanation

You get an ArrayBuffer of integers nums. Return an ArrayBuffer with every number except the first and the last.

The numbers in between keep their order. When nums has only two numbers, return an empty ArrayBuffer.

 

Example 1:

Input: nums = [4, 8, 15, 16, 23]
Output: [8, 15, 16]
Explanation: 4 is the first number and 23 is the last.
Both are left out.

Example 2:

Input: nums = [9, 0, 9]
Output: [0]
Explanation: Both 9s are ends.
Only the 0 is between them.

Example 3:

Input: nums = [1, 2]
Output: []
Explanation: 1 and 2 are the ends.
Nothing is between them.

 

Constraints:

  • nums has 2 to 10 numbers.
  • Every number is an integer from -1000 to 1000.
STEP 1 OF 2
    Ctrl + Enter to check

    SCALA · ARRAYS - CHALLENGES

    Drop The Ends in Scala, explained

    Problem overview

    The method dropEnds gets an ArrayBuffer[Int] named nums with at least two numbers. It returns a new buffer with every number except the first and the last, in the same order.

    For [4, 8, 15, 16, 23] the ends are 4 and 23, so the result is [8, 15, 16]. For [9, 0, 9] only the 0 is between the ends, so the result is [0]. For [1, 2] there is nothing between the ends, and the result is empty.

    Approach

    The numbers to keep sit at indexes 1 up to the last index minus one. slice(i, j) copies from index i up to but not including j, so both ends take care of themselves:

    • starting at index 1 leaves out the first number;
    • ending at nums.size - 1 leaves out the last number, because the last number sits at index nums.size - 1 and the end index is excluded.

    With five numbers the slice is slice(1, 4): indexes 1, 2 and 3.

    Step by step

    1. Slice from 1 to nums.size - 1 and store the copy in a val named middle.
    2. Return middle. With two numbers it is slice(1, 1), which is empty: nothing lies between the ends.

    Tracing one input

    Take nums = [3, 8, 1, 9, 4]. Its size is 5, so the last index is 4 and the call is nums.slice(1, 5 - 1), that is slice(1, 4). The result is ArrayBuffer(8, 1, 9). The 3 at index 0 is skipped because the slice starts at index 1, and the 4 at index 4 is skipped because the slice stops before index 4. Nothing else needs to be checked, so the method has no loop and no if.

    The solution in Scala

    class Solution {
        def dropEnds(nums: ArrayBuffer[Int]): ArrayBuffer[Int] = {
            val middle = nums.slice(1, nums.size - 1)
            return middle
        }
    }
    

    Details worth knowing:

    • size is the number of items, so the last index is size - 1. Using size - 1 as the end of a slice therefore stops just before the last item.
    • The result is a copy. nums still has all its numbers afterwards.
    • Scala's slice never throws for a range that holds nothing. Even a buffer with one number gives an empty result: ArrayBuffer(7).slice(1, 0) prints ArrayBuffer(). The constraints guarantee at least two numbers anyway.

    Edge cases and common mistakes

    • Exactly two numbers. The result is empty, and the empty buffer is a correct answer.
    • Ending at nums.size. That keeps the last number. The end must be nums.size - 1.
    • Starting at 0. That keeps the first number. Start at 1.
    • Equal ends. In [9, 0, 9] both ends have the same value. Slicing works by position, not value, so it is not confused by that.

    If you ever need the same slice for a buffer that might have fewer than two numbers, slice keeps you safe: there is no index to go out of range, only an empty answer.

    Another way

    You can say the same thing by name: nums.drop(1).dropRight(1) removes one item from the front, then one from the back, and gives ArrayBuffer(8, 1, 9) for [3, 8, 1, 9, 4]. For a buffer of two numbers it gives an empty buffer, as slice does. The version with slice says exactly which indexes you keep, which makes it easier to check by hand.

    Testing

    [4, 8, 15, 16, 23]  ->  8 15 16
    [9, 0, 9]           ->  0
    [1, 2]              ->  (empty)
    
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free