Three Consecutive Odds

medium

By - Aman Pareek

Last Updated - 04/09/2024

Problem Statement

You are given an integer array arr. Your task is to determine if there are three consecutive odd numbers anywhere in the array. If such a sequence exists, return true. If not, return false.

Example 1

Input: array = [2,6,4,1]

Output: false

Example 2

Input: array = [1,2,34,3,4,5,7,23,12]

Output: true

Constraints

  • The array will contain at least one element and at most 1000 elements.

  • Each integer in the array will be between 1 and 1000, inclusive.

Solution 1: Basic Loop Approach

function threeConsecutiveOddsBasicLoop(arr) {
    for (let index = 0; index < arr.length - 2; index++) {
        if (arr[index] % 2 !== 0 && arr[index + 1] % 2 !== 0 && arr[index + 2] % 2 !== 0) {
            return true;
        }
    }
    return false;
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsBasicLoop(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsBasicLoop(array2);  //output: true 

Solution 2: Using Array.prototype.some()

function threeConsecutiveOddsSome(arr) {
    return arr.some((_, idx) => idx <= arr.length - 3 &&
        arr[idx] % 2 !== 0 &&
        arr[idx + 1] % 2 !== 0 &&
        arr[idx + 2] % 2 !== 0
    );
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsSome(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsSome(array2);  //output: true 

Solution 3: Sliding Window Approach

function threeConsecutiveOddsSlidingWindow(arr) {
    let oddCount = 0;
    for (const value of arr) {
        if (value % 2 !== 0) {
            oddCount++;
            if (oddCount === 3) return true;
        } else {
            oddCount = 0;
        }
    }
    return false;
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsSlidingWindow(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsSlidingWindow(array2);  //output: true 

Solution 4: Using Array.prototype.filter()

function threeConsecutiveOddsFilter(arr) {
    let filteredOdds = arr.filter(number => number % 2 !== 0);
    for (let position = 0; position < filteredOdds.length - 2; position++) {
        if (filteredOdds[position + 1] === filteredOdds[position] + 2 &&
            filteredOdds[position + 2] === filteredOdds[position] + 4) {
            return true;
        }
    }
    return false;
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsFilter(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsFilter(array2);  //output: true 

Solution 5: Using Array.prototype.reduce()

function threeConsecutiveOddsReduce(arr) {
    let count = 0;
    return arr.reduce((found, current) => {
        if (current % 2 !== 0) {
            count++;
            if (count === 3) {
                return true;
            }
        } else {
            count = 0;
        }
        return found;
    }, false);
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsReduce(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsReduce(array2);  //output: true 

Solution 6: Using Array.prototype.every()

function threeConsecutiveOddsEvery(arr) {
    return arr.some((_, idx) => idx <= arr.length - 3 &&
        [arr[idx], arr[idx + 1], arr[idx + 2]].every(num => num % 2 !== 0)
    );
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsEvery(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsEvery(array2);  //output: true 

Solution 7: Using a Custom Helper Function

function threeConsecutiveOddsHelper(arr) {
    for (let i = 0; i < arr.length - 2; i++) {
        if (isOdd(arr[i]) && isOdd(arr[i + 1]) && isOdd(arr[i + 2])) {
            return true;
        }
    }
    return false;
}

function isOdd(num) {
    return num % 2 !== 0;
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsHelper(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsHelper(array2);  //output: true 

Solution 8: Using Array.prototype.find()

function threeConsecutiveOddsFind(arr) {
    return arr.find((_, idx) => idx <= arr.length - 3 &&
        arr[idx] % 2 !== 0 &&
        arr[idx + 1] % 2 !== 0 &&
        arr[idx + 2] % 2 !== 0
    ) !== undefined;
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsFind(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsFind(array2);  //output: true 

Solution 9: Using a Pointer Approach

function threeConsecutiveOddsPointer(arr) {
    let start = 0;
    while (start <= arr.length - 3) {
        if (arr[start] % 2 !== 0 && arr[start + 1] % 2 !== 0 && arr[start + 2] % 2 !== 0) {
            return true;
        }
        start++;
    }
    return false;
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsPointer(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsPointer(array2);  //output: true 

Solution 10: Using Array.prototype.findIndex()

function threeConsecutiveOddsFindIndex(arr) {
    const index = arr.findIndex((_, idx) => 
        idx <= arr.length - 3 &&
        arr[idx] % 2 !== 0 &&
        arr[idx + 1] % 2 !== 0 &&
        arr[idx + 2] % 2 !== 0
    );
    return index !== -1;
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsFindIndex(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsFindIndex(array2);  //output: true 

Solution 11: Using a Queue Approach

function threeConsecutiveOddsQueue(arr) {
    let queue = [];
    for (const num of arr) {
        queue.push(num);
        if (queue.length > 3) {
            queue.shift();
        }
        if (queue.length === 3 && queue.every(n => n % 2 !== 0)) {
            return true;
        }
    }
    return false;
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsQueue(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsQueue(array2);  //output: true 

Solution 12: Using Array.prototype.map() and Array.prototype.some()

function threeConsecutiveOddsMap(arr) {
    const oddMap = arr.map(num => num % 2 !== 0);
    return oddMap.some((val, idx) => idx <= oddMap.length - 3 &&
        val && oddMap[idx + 1] && oddMap[idx + 2]
    );
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsMap(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsMap(array2);  //output: true 

Solution 13: Using Array.prototype.forEach() with External State

function threeConsecutiveOddsForEach(arr) {
    let count = 0;
    let result = false;
    arr.forEach(num => {
        if (num % 2 !== 0) {
            count++;
            if (count === 3) {
                result = true;
            }
        } else {
            count = 0;
        }
    });
    return result;
} 

const array1 = [2,6,4,1];
threeConsecutiveOddsForEach(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
threeConsecutiveOddsForEach(array2);  //output: true 

Solution 14: Using a Recursion Approach

function hasThreeConsecutiveOddsRecursive(arr, index = 0) {
    if (index > arr.length - 3) {
        return false;
    }
    if (arr[index] % 2 !== 0 && arr[index + 1] % 2 !== 0 && arr[index + 2] % 2 !== 0) {
        return true;
    }
    return hasThreeConsecutiveOddsRecursive(arr, index + 1);
} 

const array1 = [2,6,4,1];
hasThreeConsecutiveOddsRecursive(array1);  //output: false 

const array2 = [1,2,34,3,4,5,7,23,12];
hasThreeConsecutiveOddsRecursive(array2);  //output: true