Time: , space:
.
class Solution:
def numSteps(self, s: str) -> int:
# convert s into int
n = 0
for c in s:
d = 1 if c == '1' else 0
n = 2*n + d
# simulate and count
steps = 0
while n != 1:
if n%2 == 0:
n //= 2
else:
n += 1
steps += 1
return steps
Observations
- We can simulate the operations one digit at a time.
- If we start with an even number like 12, we divide by 2 and end up with 6. End result here is a right shifted number. On the other hand, if we start with an odd number like 11, we first add 1 to make it 12, then we divide by 2 and end up with 6. End result here is again a right shifted number but after two operations instead of one.
- Since we are supposed to stop when the number is 1, we may have processed one digit too many. So, we may need to correct the
step_count, like in the case below. So, we keep track ofprev_carryas well.

class Solution:
def numSteps(self, s: str) -> int:
step_count = 0
prev_carry, carry = 0, 0
for i in range( len(s)-1, -1, -1 ):
curr_sum = (1 if s[i] == '1' else 0) + carry
curr_digit = 1 if curr_sum == 1 else 0
prev_carry = carry
carry = 0 if curr_sum == 0 else 1
if curr_digit == 0: # right shift
step_count += 1
else: # add 1 and right shift
step_count += 2
return step_count if prev_carry else step_count-2
Or, more concisely:
class Solution:
def numSteps(self, s: str) -> int:
step_count = 0
prev_carry, carry = 0, 0
for i in range( len(s)-1, -1, -1 ):
prev_carry = carry
carry, curr_digit = divmod(int(s[i])+prev_carry, 2)
if curr_digit == 0: # right shift
step_count += 1
else: # add 1 and right shift
carry = 1 # effect of add 1
step_count += 2
return step_count if prev_carry else step_count-2
Leave a comment