Start learning free

LESSON 143 OF 348 · LOOPS & GLOBAL VARIABLES

Maximum Value in an Array in TypeScript: One Pass, O(n)

Practice Read the full explanation

Given an array of integers, return the maximum value from the array.

Example:

Input: nums = [2, 7, 11, 8, 11, 8, 3, 11]
Output: 11
Explanation: The maximum value is 11

Note:

Do not use builtin functions such as Math.max(), it would defy the purpose of the challenge. Write the whole code yourself.

STEP 1 OF 4
    Ctrl + Enter to check

    TYPESCRIPT · LOOPS & GLOBAL VARIABLES

    Max In Array in TypeScript, explained

    Problem overview

    The method maxInArray receives an array of integers, nums, and returns the largest one. For [2, 7, 11, 8, 11, 8, 3, 11] the answer is 11. The value 11 appears three times, but the method returns it once, as a value.

    The statement tells you not to use a built-in such as Math.max() on the whole array, so the loop is yours to write. The reference solution does call Math.max, but only to compare two numbers inside the loop.

    Approach: remember the best value so far

    Imagine reading the numbers one at a time and keeping a note of the biggest one you've seen. Each new number is compared with the note. If the new number is bigger, the note changes. After the last number, the note holds the maximum.

    In code, the note is a variable, maxVal. The only decision is its starting value. Starting at 0 looks natural but is wrong: for [-5, -2, -9] every element is below 0, so the variable would keep 0, a number that isn't even in the array. The safe start is the first element, nums[0]. Whatever the array holds, the first element is a real candidate for the maximum.

    Step by step

    1. Declare maxVal with let, typed as number, and set it to nums[0]. The variable changes during the loop, so it can't be const.
    2. Loop over nums with for...of. The loop variable val holds one element per pass. Its first value is the first element again, which is harmless: comparing a number with itself changes nothing.
    3. Keep the larger value. The line maxVal = Math.max(maxVal, val) assigns the larger of the two numbers to maxVal. After every pass, maxVal is the largest value seen so far.
    4. Return maxVal after the loop, once every element has been considered.

    The solution in TypeScript

    class Solution {
        maxInArray(nums: number[]): number {
            let maxVal: number = nums[0];
            for (let val of nums) {
                maxVal = Math.max(maxVal, val);
            }
            return maxVal;
        }
    }
    

    Some TypeScript details:

    • Math.max with two arguments. It returns the larger of its arguments. Here it replaces an if (val > maxVal) { maxVal = val; } and means the same thing.
    • Indexing returns number, even when the index is missing. With the compiler settings used here, nums[0] has the type number. If the array were empty, the JavaScript would hold undefined there, and the annotation would not warn you. That is the reason the empty array deserves a thought, below.
    • Types vanish at run time. nums: number[] checks nothing when the program runs. Only the values decide what happens.
    • The spread trap. Math.max(...nums) is the shortcut the lesson avoids. Besides defeating the exercise, spreading a very large array into function arguments can fail with a stack error, whereas the loop has no such limit.

    Complexity

    Time: O(n), where n is the length of nums. Each element is compared once.

    Space: O(1). The method keeps maxVal and the loop variable only.

    Edge cases and common mistakes

    • All negative numbers. [-5, -2, -9] returns -2 because maxVal starts at -5. A start at 0 would return 0.
    • A single element. [4] returns 4; nothing larger ever appears.
    • Duplicates of the maximum. They make no difference. The maximum is a value, not a position.
    • An empty array. There is no maximum. The reference solution starts from nums[0], which is undefined for an empty array, and the method returns undefined without throwing. The lesson's tests use non-empty arrays. Real code should check nums.length first and decide what an empty input means.
    • Starting with a made-up small value. Any fixed constant, such as -1000, fails when the data contains something smaller. The first element is always safe.
    • Returning inside the loop, which would stop after the first element.

    Testing

    • [2, 7, 11, 8, 11, 8, 3, 11] gives 11.
    • [-5, -2, -9] gives -2.
    • [4] gives 4.
    • [3, 9, 1] gives 9.
    Keep going with TypeScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free