From edaa0852ca5a9d159afb21c10321b6da840179c5 Mon Sep 17 00:00:00 2001 From: anebz Date: Fri, 20 Mar 2020 16:56:04 +0100 Subject: [PATCH] 5.3. flip bit to win v1 --- 05. Bit manipulation/5.3. Flip Bit to Win.md | 125 +++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 05. Bit manipulation/5.3. Flip Bit to Win.md diff --git a/05. Bit manipulation/5.3. Flip Bit to Win.md b/05. Bit manipulation/5.3. Flip Bit to Win.md new file mode 100644 index 0000000..dc6d8b0 --- /dev/null +++ b/05. Bit manipulation/5.3. Flip Bit to Win.md @@ -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 +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 +using namespace std; + +bool findPosof0(int num) { + int i = sizeof(num) * 8; // number of bits in num + vector 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 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 + +> \ No newline at end of file