You are given a non-negative integer num
. Your task is to determine the number of steps required to reduce it to zero following these rules:
For example:
num = 14
, the steps are as follows:
num = 8
, the steps are:
num = 123
, the total number of steps is 12.Write a function that takes a non-negative integer num
as input and returns the number of steps required to reduce it to zero.
A straightforward approach is to simulate the process as described in the problem statement. We can use a while
loop to continue the process until the number becomes zero. Inside the loop, we check if the number is even or odd. If it's even, we divide it by 2; otherwise, we subtract 1. We increment a counter in each step to keep track of the number of steps.
def numberOfSteps_naive(num: int) -> int:
steps = 0
while num > 0:
if num % 2 == 0:
num //= 2
else:
num -= 1
steps += 1
return steps
O(n), where n is the input number num
. In the worst case, when num
is a power of 2, it takes log2(num) divisions. When num
is close to a power of 2 minus 1, it takes n steps.
O(1), as we use only a constant amount of extra space.
We can optimize the solution by using bit manipulation. Notice that:
0
in binary representation, and dividing by 2 is equivalent to a right shift operation. Each right shift requires one step.1
in binary representation, and subtracting 1 changes the rightmost 1
to 0
. Each subtraction also requires one step.The number of steps is equal to the number of bits (excluding the most significant bit which is handled slightly differently) plus the number of 1s minus 1. The reason we subtract 1 from the total number of 1s is that the last 1 will cause the number to become zero after subtraction (so the division after that subtraction is not counted).
Edge cases to consider:
num
is 0, return 0.num
is 1, return 1.def numberOfSteps(num: int) -> int:
if num == 0:
return 0
steps = 0
while num > 0:
if num % 2 == 0:
num >>= 1
else:
if num == 1:
steps += 1
break
num -= 1
steps += 1
return steps
Another way to simplify the optimal approach is to convert the integer to its binary string representation and then count the number of operations. The number of steps will be len(binary_string) - 1 + number_of_ones
def numberOfSteps_optimal(num: int) -> int:
if num == 0:
return 0
binary = bin(num)[2:]
ones = binary.count('1')
return len(binary) - 1 + ones
O(log n), where n is the input number num
. Converting to binary and counting ones take log n steps, where n is the input number.
O(1) in first optimal solution. In the second optimal solution, O(log n) to store the binary string.