Start learning free

LESSON 144 OF 348 · LOOPS & GLOBAL VARIABLES

Odd Numbers vs Even Numbers in TypeScript: Counting in One Pass

Practice Read the full explanation

Given an array, return true if there are more odd numbers than even numbers, otherwise return false.

Example:

Input: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
Output: true

Explanation:
There are 5 odd numbers in the array: 1, 3, 5, 7, 9
There are 4 even numbers in the array: 2, 4, 6, 8
5 is greater than 4, so our functions should return true
STEP 1 OF 5
    Ctrl + Enter to check

    TYPESCRIPT · LOOPS & GLOBAL VARIABLES

    Odd Even in TypeScript, explained

    Problem overview

    The method oddEven receives an array of numbers and returns true if the array has more odd numbers than even numbers, and false otherwise. For [1, 2, 3, 4, 5, 6, 7, 8, 9] there are five odd numbers (1, 3, 5, 7, 9) and four even ones (2, 4, 6, 8). Five is greater than four, so the answer is true. A tie is not "more", so it returns false.

    Approach: two counters and a comparison

    The method has to know two numbers, how many odd and how many even, so it keeps two counters. One pass over the array decides, for each element, which counter to increase. When the pass ends, a single comparison of the counters gives the answer.

    A number is even when dividing it by 2 leaves a remainder of 0, and odd otherwise. Every number is one or the other, so each element increments exactly one counter, and an if with an else is enough.

    Step by step

    1. Declare both counters in one statement. let oddNumbers = 0, evenNumbers = 0; creates two variables, each with its own starting value. They use let because the loop changes them, and TypeScript infers number from the zeros.
    2. Loop with for...of. The loop variable number is declared with const: each pass gets a fresh variable, and the loop body never reassigns it.
    3. Test for odd. The condition is number % 2 !== 0, and a true result increments oddNumbers.
    4. Handle the rest with else. When the remainder is 0, the number is even and evenNumbers goes up. The else runs exactly when the if condition is false.
    5. Return the comparison. oddNumbers > evenNumbers is already a boolean, so the method returns it directly.

    The solution in TypeScript

    class Solution {
        oddEven(numbers: number[]): boolean {
            let oddNumbers = 0, evenNumbers = 0;
            for (const number of numbers) {
                if (number % 2 !== 0) {
                    oddNumbers++;
                } else {
                    evenNumbers++;
                }
            }
            return oddNumbers > evenNumbers;
        }
    }
    

    The TypeScript details to know:

    • The remainder keeps the sign of the left operand. In TypeScript 3 % 2 is 1, but -3 % 2 is -1. This is why the solution tests !== 0. A test written as number % 2 === 1 would treat -3 as even.
    • -4 % 2 is -0. Negative zero is a real value in JavaScript numbers, but it is equal to 0 under === and !==, so negative even numbers are still counted as even.
    • !== is the strict form of !=. It doesn't convert types before comparing.
    • A parameter and a variable can both be called number. number is the name of a type, but it is also usable as a variable name, because types and values live in separate worlds. Using the plural parameter numbers and the singular loop variable number is easy to read.
    • Other ways to test oddness. Math.abs(number) % 2 === 1 works too, because the absolute value removes the sign before the remainder is taken. The lesson's !== 0 test is shorter and needs no extra call, and it states the rule plainly: a number is odd when dividing by 2 leaves anything other than zero.
    • Annotations are erased. numbers: number[] and : boolean don't exist in the compiled JavaScript.

    A trace of the loop

    Follow the counters on [4, -7, 10, 3]. Both start at 0.

    1. 4 % 2 is 0, so evenNumbers becomes 1.
    2. -7 % 2 is -1, which differs from 0, so oddNumbers becomes 1.
    3. 10 % 2 is 0, so evenNumbers becomes 2.
    4. 3 % 2 is 1, so oddNumbers becomes 2.

    The loop ends with 2 odd and 2 even, and 2 > 2 is false, so the method returns false. If you only need the final comparison, one counter would do: add 1 for each odd number and subtract 1 for each even one, then return whether the balance is above 0. Two counters are easier to read and match the wording of the problem.

    Complexity

    Time: O(n), where n is the length of the array. The loop does one remainder operation and one increment per element.

    Space: O(1). Two counters and the loop variable.

    Edge cases and common mistakes

    • Negative numbers. [-3, -1, 2] has two odd values and one even, so the answer is true. With the === 1 test, both negatives would be counted as even and the method would return false.
    • All even or all odd. An array of only odd numbers, such as [1, 3], returns true, since two is more than zero. Only even numbers give false.
    • A tie. [1, 2] has one odd and one even, so the answer is false. The comparison must be >, not >=.
    • An empty array. Both counters stay at 0, and 0 > 0 is false.
    • Zero counts as even. 0 % 2 is 0, so it increments evenNumbers.
    • Non-integers. The task is about integers. A value such as 3.5 gives 3.5 % 2 === 1.5, which is not 0, so this code would count it as odd. Don't feed it fractions.
    • Returning inside the loop. It would judge the array by its first element.

    Testing

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