forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 14
/
minimum-one-bit-operations-to-make-integers-zero.cpp
67 lines (64 loc) · 1.69 KB
/
minimum-one-bit-operations-to-make-integers-zero.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Time: O(logn)
// Space: O(1)
// reference: https://en.wikipedia.org/wiki/Gray_code
class Solution {
public:
int minimumOneBitOperations(int n) {
// [observation]
// n f(n)
// 000 0
// 001 1
// 011 2
// 010 3
// 110 4
// 111 5
// 101 6
// 100 7
// f(0XX...X) + f(1XX...X) = f(100...0) implies n is a gray code
// => f(n) is actually the inverse of gray code
return gray_to_binary(n);
}
private:
int gray_to_binary(int n) {
int result = 0;
for (; n > 0; n >>= 1) {
result ^= n;
}
return result;
}
};
// Time: O(logn)
// Space: O(1)
class Solution2 {
public:
int minimumOneBitOperations(int n) {
// [observation1]:
// f(1) = 1
// f(10) = 2 * f(1) + 1 = 3
// f(100) = 2 * f(10) + 1 = 7
// by mathematical induction
// => f(2^k) = 2^(k+1)-1
//
// [observation2]:
// n f(n)
// 000 0
// 001 1
// 011 2
// 010 3
// 110 4
// 111 5
// 101 6
// 100 7
// let pos be an array of positions where the bit is 1 in ascending order:
// f(0XX...X) + f(1XX...X) = f(100...0)
// f(1XX...X) = f(100...0) - f(0XX...X)
// = (2^(pos[k-1]+1)-1) - f(0XX...X)
// by mathematical induction
// => f(n) = (2^(pos[k-1]+1)-1) - (2^(pos[k-2])+1) + ... + (-1)^(k-1) * (2^(pos[0]+1)-1)
int result = 0;
for (; n > 0; n &= n - 1) {
result = -(result + (n ^ (n - 1)));
}
return abs(result);
}
};