- Published on
Recurrence relation - when division strategy differs based on whether n is even or odd
- Authors
- Name
- Ajay Karthick Senthil Kumar
- @i_ajaykarthick
The idea of divide and conquer is quite appealing. We divide the problem into subproblems that are smaller instances of the original problem, then solve them recursively, and finally, the solutions to the subproblems are combined back to form the solution to the major problem.
When an algorithm contains a recursive call to itself, we can describe the running time by a recurrence equation.
Often, divide and conquer algorithms divide the problem into subproblems by either multiplying by a fraction (for example, , ) or subtraction (for example, , ). Here, we are going to see an interesting case when an algorithm alters the strategy to break the problem into subproblems based on whether the size of the input is odd or even.
Pseudo code of this kind of algorithm may look like:
function f(n) {
if (n == 0) return 1
if (n % 2 == 0) return f(n / 2) + 1
else return 2 * f(n - 1)
}
Here, we are not interested in the output of the above function but the time complexity of these kinds of algorithms and especially the approach to solve the recurrence equation for algorithms that follow this kind of pattern.
The recurrence equation for the above function can be written as follows:
It means whenever the value of is greater than 0 and divisible by 2 (when is an even number), the function recursively calls itself with half of the value of , and whenever the value of is greater than 0 and not divisible by 2 (when is an odd number), the function recursively calls itself with .
can possibly be any integer greater than or equal to zero.
- When , it takes a constant amount of operations.
- When is odd, the algorithm reduces the value of and calls recursively with . As is an odd number, it is guaranteed that is an even number.
- When is even, the algorithm reduces the value of by halving it and calls recursively with . With the evidence of being even, we cannot conclude that is odd or even. It can be either even or odd. We need more information about to determine whether is odd or even. Since we are dividing by 2, whether becomes odd or even depends on being a power of 2.
- When is a power of 2, i.e., , it is obviously an even number and is definitely an even number for all .
So, we can conclude that when is a power of 2 and greater than 2, i.e., and , is even; otherwise, may be odd.
So, there are four cases for :
- is even and a power of 2
- is even but not a power of 2
- is odd
is even and a power of 2
Case 2:Let where .
We have:
By applying this recursively:
Continuing this way until we reach :
Assuming and :
Therefore:
Since , we have:
Thus, the time complexity for this case is .
is even but not a power of 2, or is odd
Cases 3 and 4:is odd:
WhenFor odd:
Since is even, we can then apply:
Therefore:
is even but not a power of 2:
WhenFor even and not a power of 2, we repeatedly apply the recurrence:
However, may be odd or even. We continue this process, reducing until it becomes either 1 or 0.
Generalization Using Binary Representation
An effective way to analyze the recurrence is by considering the binary representation of .
- Each time we halve (when is even), it corresponds to a right shift in binary.
- Each time we subtract 1 (when is odd), it flips the least significant bit from 1 to 0.
We can model the total time as the sum of:
- The number of times we halve : equal to the number of bits in .
- The number of times we subtract 1: equal to the number of ones in the binary representation of .
Let:
Then, the total time complexity is:
for some constants and .
Since both and are , we have:
Conclusion
The time complexity of the algorithm is .
Key Takeaways:
- The recurrence alters its strategy based on whether is even or odd.
- By analyzing the binary representation of , we can determine the time complexity.
- The total time complexity depends on both the length of in binary and the number of ones in its binary representation.
- The algorithm runs in logarithmic time relative to the input size .
Final Result: