1523. Count Odd Numbers in an Interval Range
Problem Description
In this problem, you are given two non-negative integers low
and high
. The task is to find and return the count of odd numbers that are between low
and high
(inclusive). In other words, you need to determine the number of odd numbers in the integer range starting from low
to high
, including both low
and high
if they happen to be odd.
Intuition
The intuition behind the solution lies in understanding how odd and even numbers are distributed in a range of integers. Consider any two consecutive numbers, one will always be even, and the other will be odd. Thus, in any range of integers, the count of odd and even numbers should be roughly equal.
However, the exact count may vary depending on the parity of low
and high
and whether the range includes an odd or even number of integers. The trick to solving this efficiently is to use a formula that captures this observation without having to iterate over each number in the range.
Here's how the solution is derived:
- The number of integers in the range
low
tohigh
(inclusive) can be given byhigh - low + 1
. - For a range starting from 1 to a number
n
, the number of odd numbers can be calculated by(n + 1) // 2
. This is because the sequence of odd and even numbers is regular, and half of the numbers up ton
will be odd (plus one for oddn
). - If
low
andhigh
are both odd or both even, the ranges from 1 tolow - 1
and 1 tohigh
contain the same number of odd and even numbers. The difference of these two will give us the count of odd numbers betweenlow
andhigh
. - If
low
is odd andhigh
is even (or vice versa), then we have to adjust our calculation to ensure we count the extra odd or even number at the start of the range.
So, the formula ((high + 1) >> 1) - (low >> 1)
does exactly this by effectively calculating the count of odd numbers from 1 to high
and subtracting the count of odd numbers from 1 to low - 1
. The >> 1
is a bit-shift operation that divides the number by 2, which is the same as using // 2
for integers but may be faster in certain contexts.
This results in a simple, efficient solution that exploits the pattern in which odd and even numbers occur within ranges.
Learn more about Math patterns.
Solution Approach
The solution uses an efficient mathematical approach rather than brute-forcing through the range to count odd numbers. The key observations made about the distribution of odd and even numbers in a range are used to derive a simple formula. Here is a step-by-step breakdown of the implementation:
-
The expression
(high + 1) >> 1
calculates the number of odd numbers from the range1
tohigh
. The termhigh + 1
adds one more count to facilitate the correct division by 2 (since we are interested in odd numbers). The bit-shift operation>> 1
is effectively dividing the value by2
. -
Similarly, the expression
(low >> 1)
calculates the number of odd numbers in the range from1
tolow - 1
. This works becauselow
itself is not included and the bit-shift by one position to the right divideslow
by2
. Iflow
is odd, subtracting one before division gives the correct count of odd numbers belowlow
. -
By subtracting the count of odd numbers below
low
from the count of odd numbers up to and includinghigh
, what remains is the count of odd numbers in the inclusive range betweenlow
andhigh
.
The implementation relies on no other algorithms or data structures. No loops or recursive calls are used. It is a direct application of an arithmetic operation and a bit-shift, which are both O(1) time complexity operations. The efficiency of the solution is a result of the formula which uses the inherent pattern of alternating odd and even numbers.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's work through a small example to illustrate the solution approach. Consider the range of integers from low = 3
to high = 7
. We want to count how many odd numbers there are between 3 and 7, inclusive.
Here are the numbers in the range: 3, 4, 5, 6, 7. The odd numbers are 3, 5, and 7. There are 3 odd numbers in this range.
Now let's use the solution approach to get the same result:
-
We calculate the number of odd numbers up to
high
with the expression(high + 1) >> 1
. Forhigh = 7
, this gives us(7 + 1) >> 1
, which is8 >> 1
. Bit-shifting8
one position to the right is the same as dividing8
by2
, which gives us4
. So there are 4 odd numbers from 1 to 7 inclusive. -
We calculate the number of odd numbers before
low
with the expression(low >> 1)
. Forlow = 3
, this gives us3 >> 1
, which is1
when rounded down (as the bit-shifting operation inherently does for integers). So, there is 1 odd number in the range 1 to 2 (sincelow
is not included). -
We find the count of odd numbers between
low
andhigh
by subtracting the count of odd numbers belowlow
from the count of odd numbers up tohigh
. In this case, we subtract1
from4
to get3
, which is the count of odd numbers in the range of 3 to 7 inclusive.
As evidenced by the example, the formula ((high + 1) >> 1) - (low >> 1)
correctly calculates the number of odd numbers within a given range without the need for iterating over all elements in the range, which is much more efficient for larger ranges.
Using this approach with our example range from low = 3
to high = 7
, we've demonstrated that there are indeed 3 odd numbers, matching our earlier manual count.
Solution Implementation
1class Solution:
2 def count_odds(self, low: int, high: int) -> int:
3 # Calculate the number of odds between two numbers low and high (inclusive).
4 # The formula ((high + 1) >> 1) calculates how many odd numbers are in
5 # the range from 0 to high inclusive by dividing the endpoint by 2 and
6 # rounding up, if necessary.
7 # Similarly, (low >> 1) calculates how many odd numbers there are from
8 # 0 up to but not including low.
9 # The difference between these two quantities gives the count of odd numbers
10 # in the range [low, high].
11 return ((high + 1) >> 1) - (low >> 1)
12
1class Solution {
2 // Function to count the number of odd numbers between low and high (inclusive)
3 public int countOdds(int low, int high) {
4 // ((high + 1) >> 1) calculates the number of odd numbers from 1 to high
5 // (low >> 1) calculates the number of odd numbers from 1 to (low - 1)
6 // Subtracting the two gives the number of odd numbers between low and high
7 return ((high + 1) >> 1) - (low >> 1);
8 }
9}
10
1class Solution {
2public:
3 // Function to count the number of odd numbers within a given range.
4 int countOdds(int low, int high) {
5 // Calculate the number of odd numbers before 'high' and 'low'.
6 // Use bitwise right shift to divide by 2. Adding 1 to 'high' handles the case when 'high' is odd.
7 int oddsBeforeHigh = (high + 1) >> 1;
8 int oddsBeforeLow = low >> 1;
9
10 // The number of odd numbers within the range is the difference
11 // of the two calculated values.
12 int countOfOdds = oddsBeforeHigh - oddsBeforeLow;
13
14 // Return the count of odd numbers in the range.
15 return countOfOdds;
16 }
17};
18
1// This function counts the number of odd numbers in the range [low, high].
2// It leverages bitwise operations to efficiently perform the calculation.
3function countOdds(low: number, high: number): number {
4 // Increment the upper bound (`high`) by 1 and then shift it one bit to the right.
5 // This effectively divides `high + 1` by 2, rounding down to the nearest integer.
6 // This calculation returns the number of odd numbers from 0 up to `high`.
7 const oddCountUpToHigh: number = (high + 1) >> 1;
8
9 // Shift `low` one bit to the right to divide it by 2, rounding down to the nearest integer.
10 // This calculation returns the number of odd numbers from 0 up to `low - 1`.
11 const oddCountUpToLow: number = low >> 1;
12
13 // Subtract the number of odds up to `low - 1` from the number of odds up to `high`
14 // to get the count of odd numbers in the range [low, high].
15 return oddCountUpToHigh - oddCountUpToLow;
16}
17
Time and Space Complexity
The time complexity of the provided code is O(1)
. This is because the operations performed to calculate the number of odd numbers within the range — specifically, the additions, subtractions, and bit shifts — are constant time operations, regardless of the input size.
The space complexity of the code is also O(1)
. There are a fixed number of variables used, which does not scale with the input size, thus only a constant amount of memory is used.
Learn more about how to find time and space complexity quickly using problem constraints.
Consider the classic dynamic programming of fibonacci numbers, what is the recurrence relation?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Want a Structured Path to Master System Design Too? Don’t Miss This!