Start learning free

LESSON 122 OF 677 · ARRAYS - CHALLENGES

Drop the Ends of a List in Kotlin with subList

Practice Read the full explanation

You get an ArrayList of integers nums. Return an ArrayList 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 ArrayList.

 

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

    KOTLIN · ARRAYS - CHALLENGES

    Drop The Ends in Kotlin, explained

    Problem overview

    The function dropEnds gets a MutableList<Int> called nums with at least two numbers. It returns everything except the first and the last number, keeping the order of the rest. With exactly two numbers, nothing is between the ends, so the result is empty.

    For [4, 8, 15, 16, 23] the ends are 4 and 23, and the answer is [8, 15, 16]. For [9, 0, 9] only the 0 is left, and for [1, 2] the result is empty.

    Approach

    The first number is at index 0, so the slice starts at index 1. The last number is at index nums.size - 1. Because the end index of subList is excluded, using nums.size - 1 as the end leaves that last number out. The slice subList(1, nums.size - 1) is therefore the middle, and with two numbers it is subList(1, 1), which is empty.

    Step by step

    1. Take the middle. Call subList with 1 and nums.size - 1 and keep the result in a val named middle.
    2. Return it.

    The solution in Kotlin

    class Solution {
        fun dropEnds(nums: MutableList<Int>): MutableList<Int> {
            val middle = nums.subList(1, nums.size - 1)
            return middle
        }
    }
    

    On the three examples it gives (values separated by spaces):

    8 15 16
    0
    (empty line)
    

    As with any subList, the result is a view of nums rather than a copy. Reading it is fine for this lesson. Add .toMutableList() if you want a list that is independent of nums.

    Another way

    Kotlin's nums.lastIndex is the same as nums.size - 1, so this version reads a little more clearly:

    fun dropEnds(nums: MutableList<Int>): MutableList<Int> = nums.subList(1, nums.lastIndex)
    

    Another version builds a new list in two steps, nums.drop(1).dropLast(1).toMutableList(). Both give [8, 15, 16] for the first example and [] for [1, 2]. The lesson's steps use subList(1, nums.size - 1).

    How the indexes line up

    For [4, 8, 15, 16, 23] the size is 5, so the last index is 4. The slice runs from index 1 up to, but not including, index 5 - 1 = 4. That takes the items at indexes 1, 2 and 3, which are 8, 15 and 16. The length of the slice is 4 - 1 = 3, always two less than the length of the list.

    Edge cases and common mistakes

    • Two numbers. subList(1, 1) is empty, which is the expected 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.
    • Fewer than two numbers. The constraints rule it out. With a single number the call becomes subList(1, 0), which throws an IllegalArgumentException because the start is larger than the end.

    More cases to try

    Here are a few more inputs, with what the function returns for each. Try them in the editor above after the lesson's own tests pass:

    numsresult
    [5, 1, 5, 1][1, 5]
    [7, 7][]
    [-3, 0, 3][0]
    [1, 2, 3, 4][2, 3]

    The numbers themselves don't matter: only the positions decide what is dropped. In [5, 1, 5, 1] the 5 and 1 at the ends go, even though the same values appear in the middle. The original list is also unchanged by the call, so after taking the middle of [4, 8, 15, 16, 23] the original still holds all five numbers, and the result has size 3.

    Testing

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