5.3. flip bit to win v1
This commit is contained in:
parent
58d12aa256
commit
edaa0852ca
|
|
@ -0,0 +1,125 @@
|
||||||
|
# 5.3. Flip Bit to Win
|
||||||
|
|
||||||
|
Hints: #358,#375,#390
|
||||||
|
|
||||||
|
> You have an integer and you can flip exactly one bit from a 0 to a 1. Write code to find the length of the longest sequence of 1s you could create. Input: 1775, or 11011101111, Output: 8
|
||||||
|
|
||||||
|
Brute force idea: find all 0s, flip all of them, count all 1s sequences (how?), output max.
|
||||||
|
|
||||||
|
Another idea: find longest sequence of 1s as of now, flip adjacent 0 and count length, flip other 0 (if not end/beginning of sequence) and count length, output max.
|
||||||
|
|
||||||
|
But how to find first 0? and count consecutive 1s? And how to make it efficient?
|
||||||
|
|
||||||
|
## Hint 1
|
||||||
|
|
||||||
|
> Start with a brute force solution for each
|
||||||
|
|
||||||
|
Flipping function, need the position of the 0 bit.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
boolean setBit(int num, int i) {
|
||||||
|
return num | (1 << i);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[Length of the Longest Consecutive 1s in Binary Representation](https://www.geeksforgeeks.org/length-longest-consecutive-1s-binary-representation/). Bit magic.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include<bits/stdc++.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int maxConsecutiveOnes(int num) {
|
||||||
|
// Initialize result
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
// Count the number of iterations to reach num = 0.
|
||||||
|
while (num!=0) {
|
||||||
|
// This operation reduces length
|
||||||
|
// of every sequence of 1s by one.
|
||||||
|
num = (num & (num << 1));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```c++
|
||||||
|
11101111 (x)
|
||||||
|
& 11011110 (x << 1)
|
||||||
|
----------
|
||||||
|
11001110 (x & (x << 1))
|
||||||
|
^ ^
|
||||||
|
| |
|
||||||
|
trailing 1 removed
|
||||||
|
```
|
||||||
|
|
||||||
|
The operation x = (x & (x << 1)) reduces length of every sequence of 1s by one in binary representation of x. If we keep doing this operation in a loop, we end up with x = 0. The number of iterations required to reach 0 is the length of the longest consecutive sequence of 1s.
|
||||||
|
|
||||||
|
If I find all 0s, flip them, I can use this to find the longest sequence.
|
||||||
|
|
||||||
|
[Number of leading zeros in binary representation of a given number](https://www.geeksforgeeks.org/number-of-leading-zeros-in-binary-representation-of-a-given-number/).
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
bool findPosof0(int num) {
|
||||||
|
int i = sizeof(num) * 8; // number of bits in num
|
||||||
|
vector<int> positions;
|
||||||
|
|
||||||
|
while (i--) {
|
||||||
|
// checking if i th bit of num is 1
|
||||||
|
if (!(num & (1 << i))) {
|
||||||
|
positions.push_back(i);
|
||||||
|
}
|
||||||
|
num = (num << 1);
|
||||||
|
}
|
||||||
|
// found first 0
|
||||||
|
return positions;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num = 17;
|
||||||
|
int max1s = 0;
|
||||||
|
// finds all positions of 0
|
||||||
|
vector<int> positions0 = findPosOf0(num);
|
||||||
|
|
||||||
|
for (pos : positions0) {
|
||||||
|
// flip the first 0, returns a boolean so don't know if this works
|
||||||
|
num = setBit(num, first0);
|
||||||
|
max1s = max(max1s, maxConsecutiveOnes(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
// count consecutive 1s
|
||||||
|
cout << max1s << endl;
|
||||||
|
```
|
||||||
|
|
||||||
|
Time complexity O(2n) and space complexity O(2n).
|
||||||
|
|
||||||
|
## Hint 2
|
||||||
|
|
||||||
|
> Get Next: Picture a binary number-something with a bunch of 1s and Os spread out throughout the number. Suppose you flip a 1 to a 0 and a 0 to a 1. In what case will the number get bigger? In what case will it get smaller?
|
||||||
|
|
||||||
|
Flipping 1 to 0 makes it smaller, and vice versa.
|
||||||
|
|
||||||
|
## Hint 3
|
||||||
|
|
||||||
|
> If you flip a 1 to a 0 and a 0 to a 1, it will get bigger if the 0->1 bit is more significant than the 1->0 bit. How can you use this to create the next biggest number (with the same number of 1s)?
|
||||||
|
|
||||||
|
I don't know.
|
||||||
|
|
||||||
|
## Hint 4
|
||||||
|
|
||||||
|
> When you do a binary subtraction, you flip the rightmost 0s to a 1, stopping when you get to a 1 (which is also flipped). Everything (all the 1 s and 0s) on the left will stay put.
|
||||||
|
|
||||||
|
Yes. And in reverse, if we have a bunch of 11111s, if we add one, it will create many 0s.
|
||||||
|
|
||||||
|
## Hint 5
|
||||||
|
|
||||||
|
> Flipping a 0 to a 1 will create a bigger number. The farther right the index is the smaller the bigger number is. If we have a number like 1001, we want to flip the rightmost 0 (to create 1011). But if we have a number like 1010, we should not flip the rightmost 1.
|
||||||
|
|
||||||
|
Sure but we're not looking for the biggest , rather for the longest sequence of 1s. If we have 10111011, we should flip the second 0. In this case, flipping any 0 creates a sequence of two 1s. So it shouldn't matter :thinking:.
|
||||||
|
|
||||||
|
## Hint 6
|
||||||
|
|
||||||
|
>
|
||||||
Loading…
Reference in New Issue