Minimum One Bit Operations to Make Integers Zero
Problem
Given an integer , you must transform it into using the following operations any number of times:
- Change the rightmost bit in the binary representation of
- Change the bit in the binary representation of if the bit is set to and the through bits are set to
Return the minimum number of operations to transform into .
Example
Input: n = 3
Output: 2
Explanation: The binary representation of 3 is "11".
"11" -> "01" with the 2nd operation since the 0th bit is 1.
"01" -> "00" with the 1st operation.
Input: n = 6
Output: 4
Explanation: The binary representation of 6 is "110".
"110" -> "010" with the 2nd operation since the 1st bit is 1 and 0th through 0th bits are 0.
"010" -> "011" with the 1st operation.
"011" -> "001" with the 2nd operation since the 0th bit is 1.
"001" -> "000" with the 1st operation.
Constraints
Submit your solution at here
Solution
Observation
My solution is based on this observation:
- Let’s say we have number , in order to clear the highest , there is no other way but to make it first, and then clear the highest to form . This is not proven but I can’t find any other way to do it. So I just assume it. If you have a proof or a counter example on this I would gladly accept.
- From number , the only way to make it is by transform it to , clear the highest and then recursively do it all over again. Let is the decimal form of the number we need to clear, the number of steps needed is , or you can use bit operator with is the position of the bit,
Complexity
- Time complexity:
- Space complexity:
Code
class Solution {
public:
int costToClear(int bit) {
return (1<<(bit+1)) - 1;
}
int minimumOneBitOperations(int n) {
vector<int> f(31);// f[i] = cost to make xxxx to be 0000
vector<int> g(31);// g[i] = cost to make xxxx to be 1000
f[0] = (n&1)?1:0;
g[0] = (n&1)?0:1;
for(int i = 1;i<31;i++) {
bool isSet = (n&(1<<i)) != 0;
if(isSet) {
g[i] = f[i-1];
f[i] = g[i-1];// cost to make 1xxxx -> 11000
f[i] += 1;// cost to make 11000 -> 1000
f[i] += costToClear(i-1);// cost to make 1000 to become 0000
} else {
f[i] = f[i-1];
g[i] = g[i-1];// cost to make 0xxxx -> 01000
g[i] += 1;// cost to make 01000 -> 11000
g[i] += costToClear(i-1);// cost to make 1000 to become 0000
}
}
return f[30];
}
};