Start learning free

LESSON 149 OF 415 · LOOPS & GLOBAL VARIABLES

Odd or Even Majority in Swift: Counting with the Remainder

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 function should return true
STEP 1 OF 5
    Ctrl + Enter to check

    SWIFT · LOOPS & GLOBAL VARIABLES

    Odd Even in Swift, explained

    Problem overview

    The method oddEven receives an array of integers, numbers, and returns true when 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 values (1, 3, 5, 7, 9) and four even ones (2, 4, 6, 8). Five is more than four, so the answer is true.

    A tie returns false, since "more than" is strict.

    Approach: two counters

    Go through the array once, deciding for each number whether it is odd or even, and add one to the matching counter. At the end, compare the counters. This needs no extra array and no sorting.

    The decision rests on the remainder operator %. A number is even when dividing it by 2 leaves nothing, so number % 2 == 0. Everything else is odd.

    Trace the example. Starting with both counters at 0, the numbers 1, 2, 3, 4, 5, 6, 7, 8, 9 alternate odd, even, odd and so on. After the loop oddNumbers is 5 and evenNumbers is 4. The final comparison 5 > 4 is true.

    The loop doesn't need both counters to decide the answer. It would be enough to keep one signed tally, adding 1 for an odd number and subtracting 1 for an even one, and return whether it ends above 0. Two named counters are easier to read and to debug, and that is what the lesson uses.

    Step by step

    1. Declare two counters. oddNumbers and evenNumbers, both var and both starting at 0.
    2. Loop over the numbers. for number in numbers gives each element in turn.
    3. Count the odd ones. Test number % 2 != 0 and add 1 to oddNumbers.
    4. Count the even ones. In the else branch, add 1 to evenNumbers.
    5. Compare. After the loop, return oddNumbers > evenNumbers. The comparison is already a Bool.

    The solution in Swift

    class Solution {
        func oddEven(_ numbers: [Int]) -> Bool {
            var oddNumbers = 0
            var evenNumbers = 0
            for number in numbers {
                if number % 2 != 0 {
                    oddNumbers += 1
                } else {
                    evenNumbers += 1
                }
            }
            return oddNumbers > evenNumbers
        }
    }
    

    Swift details worth knowing:

    • The remainder keeps the sign of the left side. In Swift, -3 % 2 is -1, not 1, and -4 % 2 is 0. That is why the odd test is != 0. A test written as number % 2 == 1 misses every negative odd number.
    • % is the remainder, not a modulo. Swift's operator works with integer division that truncates toward zero, so the result takes the sign of the dividend.
    • Counters need var. With let, oddNumbers += 1 doesn't compile. The type Int is inferred from the literal 0.
    • No ++. Swift has no increment operator, so the code uses += 1.
    • Returning a comparison. An expression such as a > b is a Bool, so if a > b { return true } else { return false } can be shortened to return a > b.

    Other ways to test for evenness

    Integers have a method for this: number.isMultiple(of: 2) is true for even numbers, including 0 and negative ones. For -3 it is false, and for 4 and 0 it is true. It states the intent directly and avoids the sign question altogether. A bitwise test, number & 1, also works for negative values: it gives 1 for -3 and 0 for -4. For the lesson, the remainder operator is the tool the steps ask for, and it is worth learning how its sign behaves.

    Complexity

    Time: O(n) for n numbers. Each one costs a single remainder and one addition.

    Space: O(1). Two counters and a loop variable are all the function keeps.

    Because the check is on the remainder, the size of a number never matters, only its parity. Very large values behave like small ones, and no arithmetic here can overflow.

    Edge cases and common mistakes

    • Negative numbers. [-3, -5, 2] has two odd values and one even, so the answer is true. A test of % 2 == 1 would count both -3 and -5 as even and return false.
    • Zero. 0 is even, because 0 % 2 is 0, so it goes to the else branch and counts toward evenNumbers.
    • A tie. [1, 2] returns false.
    • Empty array. Both counters stay at 0, which is a tie, so the result is false.
    • Declaring the counters inside the loop. They would be reset on every pass and the final comparison would only see the last number: the declarations belong above the loop, where they live for the whole function.
    • Forgetting the else. Without it, the second counter would need its own condition. With it, each number lands in exactly one counter, so the two counts always add up to the length of the array.
    • Comparing the wrong way round. evenNumbers > oddNumbers answers the opposite question.

    Testing

    Work each case out by hand first, then run it in the editor above. Cases with negative numbers and with ties catch the two most common slips.

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