There is a broken calculator that has the integer startValue
on its display initially. In one operation, you can:
2
, or1
from the number on display.Given two integers startValue
and target
, return the minimum number of operations needed to display target
on the calculator.
Example 1:
Input: startValue = 2, target = 3 Output: 2 Explanation: Use double operation and then decrement operation {2 -> 4 -> 3}.
Example 2:
Input: startValue = 5, target = 8 Output: 2 Explanation: Use decrement and then double {5 -> 4 -> 8}.
Example 3:
Input: startValue = 3, target = 10 Output: 3 Explanation: Use double, decrement and double {3 -> 6 -> 5 -> 10}.
Constraints:
1 <= startValue, target <= 109
The problem asks for the minimum number of operations to transform startValue
into target
using only multiplication by 2 or subtraction by 1. A greedy approach works best here. The core idea is to work backward from the target
to startValue
, prioritizing division by 2 (when possible) because it's more efficient than multiple subtractions.
Algorithm:
Work Backwards: Instead of starting from startValue
, we begin from target
and iteratively reduce it towards startValue
.
Prioritize Division: If target
is even, we can divide it by 2, representing a single multiplication operation in the reverse direction (going from startValue
to target
).
Handle Odd Numbers: If target
is odd, we can't divide it by 2. Instead, we increment it by 1, simulating a subtraction operation in the reverse direction. This is because subtracting 1 from an odd number makes it even, and the next step can perform a more efficient division.
Final Subtraction: Once target
becomes less than or equal to startValue
, any remaining difference is handled by simple subtractions. The number of subtractions is simply startValue - target
.
Time Complexity Analysis:
The while
loop continues as long as target
is greater than startValue
. In each iteration, target
is either halved (in the best case) or incremented by one (in the worst case). The worst-case scenario is when target
is much larger than startValue
and involves many increment operations before a division becomes possible. However, the number of operations is still logarithmic with respect to the difference between target
and startValue
.
target
is a power of 2.target
is odd and much larger than startValue
. However, this is still linear with respect to the difference, not the values themselves.Therefore, the overall time complexity is considered to be O(log₂(target)) in a practical sense, which is quite efficient.
Space Complexity Analysis:
The algorithm uses a constant amount of extra space to store variables like ans
and target
. Thus, the space complexity is O(1).
class Solution:
def brokenCalc(self, startValue: int, target: int) -> int:
ans = 0
while startValue < target:
if target & 1: # Check if target is odd using bitwise AND
target += 1
else:
target >>= 1 # Divide target by 2 using right bit shift
ans += 1
ans += startValue - target # Add final subtractions
return ans
This code directly implements the algorithm described above. The bitwise operations (& 1
and >>= 1
) are efficient ways to check for odd numbers and perform division by 2, respectively. The rest of the code follows the steps outlined in the algorithm. The other language examples (Java, C++, Go) are analogous in their implementation and complexity.