Problem
Given the binary representation of an integer as a string s
, return the number of steps to reduce it to 1
under the following rules:
- If the current number is even, you have to divide it by
2
. - If the current number is odd, you have to add
1
to it.
It is guaranteed that you can always reach one for all test cases.
Examples
Example 1:
Input: s = "1101"
Output: 6
Explanation: "1101" corressponds to number 13 in their decimal representation.
Step 1) 13 is odd, add 1 and obtain 14.
Step 2) 14 is even, divide by 2 and obtain 7.
Step 3) 7 is odd, add 1 and obtain 8.
Step 4) 8 is even, divide by 2 and obtain 4.
Step 5) 4 is even, divide by 2 and obtain 2.
Step 6) 2 is even, divide by 2 and obtain 1.
Example 2:
Input: s = "10"
Output: 1
Explanation: "10" corressponds to number 2 in their decimal representation.
Step 1) 2 is even, divide by 2 and obtain 1.
Example 3:
Input: s = "1"
Output: 0
Solution
Method 1 - Carry Forward
We have already seen similar problem Number of Steps to Reduce a Number to Zero Problem, and use bits operation to solve it method 1.
We know in binary representation, if:
- Number is odd, the last or rightmost bit is 1. For eg.
111
is 7 an odd number - Number is even, the last or rightmost bit is 0. For eg.
1000
is 8 an even number
Algorithm
- Now, we will start processing the binary string from right to left, bit by bit, aka
i = [n-1..1]
- Because for odd numbers, we have to add
1
, we can define acarry
variable - Now, for each
s[i]
- If
s[i] + carry == 1
-> It’s an odd number, we need 2 operations: Add 1 and Divide by two,ans += 2
- Else if
s[i] + carry == 0
-> It’s an even number, we need 1 operation: Divide by two,ans += 1
- If
- In the end, if carry still exists, we need to increase the answer by 1
Here is the video explanation:
Code
Java
class Solution {
public int numSteps(String s) {
int carry = 0;
int ans = 0;
for (int i = s.length() - 1; i >= 1; i--) {
int dig = s.charAt(i) - '0' + carry;
// odd number
if (dig == 1) {
carry = 1;
ans += 2;
} else if (dig == 0) {
carry = 0;
ans += 1;
} else if (dig == 2) {
carry = 1;
ans += 1;
}
}
// last digit 1 needs to add a carried over digit 1,
// which gives 10 in eg. 1
// So need one more divide to make it 1, hence 1 more step
if (carry == 1) {
ans++;
}
return ans;
}
}
Method 2 - Carry Forward and even simpler
Note that once the carry is set to 1
, it is not reset to 0. Hence, we can simplify the code even more.
Code
Java
class Solution {
public int numSteps(String s) {
int carry = 0;
int ans = 0;
for (int i = s.length() - 1; i >= 1; i--) {
if (s.charAt(i) - '0' + carry == 1) {
carry = 1;
ans += 2;
} else {
ans += 1;
}
}
// last digit 1 needs to add a carried over digit 1,
// which gives 10 in eg. 1
// So need one more divide to make it 1, hence 1 more step
if (carry == 1) {
ans++;
}
return ans + carry;
}
}
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(1)
Dry Run
Suppose, s = 1101
n = 5
carry = 0
s = 1 1 0 1
index = 0 1 2 3
---
i = 3
=> s[i] = 1
carry + s[i] = 1 => odd => carry = 1, ans += 2 = 2
---
i = 2
=> s[i] = 0, carry = 1
carry + s[i] = 1 => odd => carry = 1, ans += 2 = 4
---
i = 1
=> s[i] = 1, carry = 1
carry + s[i] = 2 => even => ans += 1 = 5
---
Finally, as carry = 1, we increment ans += 1 = 6
Return ans as 6