|
| 1 | +/** |
| 2 | +
|
| 3 | + -* Reverse Bits *- |
| 4 | +
|
| 5 | +Reverse bits of a given 32 bits unsigned integer. |
| 6 | +
|
| 7 | +Note: |
| 8 | +
|
| 9 | +Note that in some languages, such as Java, there is no unsigned integer type. In this case, both input and output will be given as a signed integer type. They should not affect your implementation, as the integer's internal binary representation is the same, whether it is signed or unsigned. |
| 10 | +In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 2 above, the input represents the signed integer -3 and the output represents the signed integer -1073741825. |
| 11 | +
|
| 12 | +
|
| 13 | +Example 1: |
| 14 | +
|
| 15 | +Input: n = 00000010100101000001111010011100 |
| 16 | +Output: 964176192 (00111001011110000010100101000000) |
| 17 | +Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000. |
| 18 | +Example 2: |
| 19 | +
|
| 20 | +Input: n = 11111111111111111111111111111101 |
| 21 | +Output: 3221225471 (10111111111111111111111111111111) |
| 22 | +Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10111111111111111111111111111111. |
| 23 | +
|
| 24 | +
|
| 25 | +Constraints: |
| 26 | +
|
| 27 | +The input must be a binary string of length 32 |
| 28 | +
|
| 29 | +
|
| 30 | +Follow up: If this function is called many times, how would you optimize it? |
| 31 | +
|
| 32 | + */ |
| 33 | + |
| 34 | +class S { |
| 35 | + int reverseBits(int nums) { |
| 36 | + nums = ((nums & 0xffff0000) >>> 16) | ((nums & 0x0000ffff) << 16); |
| 37 | + nums = ((nums & 0xff00ff00) >>> 8) | ((nums & 0x00ff00ff) << 8); |
| 38 | + nums = ((nums & 0xf0f0f0f0) >>> 4) | ((nums & 0x0f0f0f0f) << 4); |
| 39 | + nums = ((nums & 0xcccccccc) >>> 2) | ((nums & 0x33333333) << 2); |
| 40 | + nums = ((nums & 0xaaaaaaaa) >>> 1) | ((nums & 0x55555555) << 1); |
| 41 | + |
| 42 | + return nums; |
| 43 | + } |
| 44 | + /* |
| 45 | + Let's understand in terms of decimal number to understand how the code is implemented |
| 46 | +Suppose we have a number 12345678 and we have to reverse it to get 87654321 as desired output |
| 47 | +The process will be as follows: |
| 48 | + 12345678 --> original number |
| 49 | +
|
| 50 | +56781234 |
| 51 | +78563412 |
| 52 | +87654321 --> desired number(reversed number) |
| 53 | +Explanation of above process is as follows: |
| 54 | +
|
| 55 | +Divide original number(12345678) into 2 parts(4 - 4 each) |
| 56 | +1234|5678 and swap with each other i.e. |
| 57 | + |_____| |
| 58 | +
|
| 59 | +5678|1234(it can also be said that we are right shifting the 1st part(1234) to 4 places from its original position and left shifting the 2nd part(5678) to 4 places from its original position) |
| 60 | +
|
| 61 | +Divide this obtained number(56781234) into 4 parts(2 - 2 each) |
| 62 | +56|78|12|34 and swap with each other i.e. |
| 63 | + |__| |__| |
| 64 | +
|
| 65 | +78|56|34|12(it can also be said that we are right shifting the 1st part(56) and 3rd part(12) to 2 places from their original positions and left shifting the 2nd part(78) and 4th part(34) to 2 places from their original positions) |
| 66 | +
|
| 67 | +Divide the obtained number(78563412) into 8 parts(1 - 1 each) |
| 68 | +7|8|5|6|3|4|1|2 and swap with each other i.e. |
| 69 | + |_| |_| |_| |_| |
| 70 | +
|
| 71 | +8|7|6|5|4|3|2|1(it can also be said that we are right shifting the 1st part(7), 3rd part(5), 5th part(3) and 7th part(1) to 1 place from their original positions and left shifting the 2nd part(8), 4th part(6), 6th part(4) and 8th part(2) to 1 place from their original positions) |
| 72 | +
|
| 73 | +We got the desired output as 87654321 |
| 74 | +
|
| 75 | +Time to play with bits!!!!!! |
| 76 | +
|
| 77 | +To get better understanding of how the 32 bits are reversed in binary, we will take 8 bits instead of 32. |
| 78 | +If the number is of 8 bits, the bits will be reversed in 3 steps as we are using Divide and Conquer approach which is nothing dividing the original problem into sub problems i.e. log(O(Number_Of_Bits)) i.e. log(O(8)) --> 3 and the same Idea applies for 32 bits where the bits will be reversed in 5 steps as log(O(32)) --> 5 |
| 79 | +
|
| 80 | +First let's understand with 8 bits |
| 81 | +Suppose we have bits as 00010111 and we have to reverse it to get 11101000 as desired output |
| 82 | +The Process will be as follows: |
| 83 | +00010111(8 bits) --> Original Number |
| 84 | +
|
| 85 | +01110001 |
| 86 | +11010100 |
| 87 | +11101000 --> Reversed Number |
| 88 | +Explanation of above process is as follows: |
| 89 | +
|
| 90 | +Divide original bits into 4 - 4 each (4 * 2 = 8 bits) |
| 91 | +0001|0111 and swap with each other i.e. |
| 92 | + |_____| |
| 93 | +0111|0001 (It can also be said that we are right shifting 1st part(first 4 bits) to 4 places from their original positions and left shifting the 2nd part(last 4 bits) to 4 places from their original positions) |
| 94 | +
|
| 95 | +Following is the process of doing it: |
| 96 | +a) Preserve 1st part(first 4 bits) and we know the property of bitwise and(&) operator i.e. 0, 1 -> 0 and 1, 1 -> 1 |
| 97 | +For this, we will take a mask in hexadecimal form and apply bitwise and(&) to preserve the first 4 bits |
| 98 | +mask = 0xf0 (which is nothing but 1111 0000 i.e. 1111(15 == f) and 0000(0)) |
| 99 | + 0001 0111 --> num |
| 100 | +& 1111 0000 --> 0xf0 |
| 101 | + 0001 0000 |
| 102 | +
|
| 103 | +b) Right shift the obtained number from its original position by 4 places i.e. (num & 0xf0) >>> 4 |
| 104 | + 00000001 |
| 105 | +
|
| 106 | +c) Preserve the 2nd part(last 4 bits) |
| 107 | +For this, will take a mask in hexadecimal form and apply bitwise and(&) to preserve the last 4 bits |
| 108 | +mask = 0x0f (which is nothing but 0000 1111 i.e. 0000(0) and 1111(15 == f)) |
| 109 | + 0001 0111 --> num |
| 110 | +& 0000 1111 --> 0x0f |
| 111 | + 0000 0111 |
| 112 | +
|
| 113 | +d) Left shift the obtained number from its original position by 4 places i.e. (num & 0x0f) << 4 |
| 114 | + 01110000 |
| 115 | +
|
| 116 | +e) Do the bitwise OR(|) operation on both shifted numbers to merge intermediate results into a single number which is used as an input for the next step. |
| 117 | + 0000 0001 --> number obtained by right shift at step b) |
| 118 | +| 0111 0000 --> number obtained by left shift at step d) |
| 119 | + 0111 0001 |
| 120 | +
|
| 121 | +f) Assign the result into num after apply bitwise or into num again to proceed further |
| 122 | + num = 01110001 |
| 123 | +Till here, 1 of 3 steps of process has been completed. 2 More remaining!!! |
| 124 | +
|
| 125 | +Divide obtained bits(01110001) into 2 - 2 each (2 * 4 = 8 bits) |
| 126 | +01|11|00|01 and swap with each other i.e. |
| 127 | + |__| |__| |
| 128 | +11|01|01|00 (It can also be said that we are right shifting 1st part(01) and 3rd part(00) to 2 places from their original positions and left shifting the 2nd part(11) and 4th part(01) to 2 places from their original positions) |
| 129 | +
|
| 130 | +Following is the process of doing it: |
| 131 | +a) Preserve 1st part(01) and 3rd part(00) and we know the property of bitwise and(&) operator i.e. 0, 1 -> 0 and 1, 1 -> 1 |
| 132 | +For this, we will take a mask in hexadecimal form and apply bitwise and(&) to preserve 1st part(01) and 3rd part(00) |
| 133 | +mask = 0xcc (which is nothing but 1100 1100 i.e. (12 == c) and (12 == c)) |
| 134 | + 01 11 00 01 --> num |
| 135 | +& 11 00 11 00 --> 0xcc |
| 136 | + 01 00 00 00 |
| 137 | +
|
| 138 | +b) Right shift the obtained number(01 00 00 00) from its original position by 2 places i.e. (num & 0xcc) >>> 2 |
| 139 | + 00 01 00 00 |
| 140 | +
|
| 141 | +c) Preserve the 2nd part(11) and 4th part(01) |
| 142 | +For this, we will take a mask in hexadecimal form and apply bitwise and(&) to preserve 2nd part(11) and 4th part(01) |
| 143 | +mask = 0x33 (which is nothing but 0011 0011 i.e. 0011(3) and 0011(3)) |
| 144 | + 01 11 00 01 --> num |
| 145 | +& 00 11 00 11 --> 0x33 |
| 146 | + 00 11 00 01 |
| 147 | +
|
| 148 | +d) Left shift the obtained number(00 11 00 01) from its original position by 2 places i.e. (num & 0x33) << 2 |
| 149 | + 11 00 01 00 |
| 150 | +
|
| 151 | +e) Do the bitwise OR(|) operation on both shifted numbers to merge intermediate results into a single number which is used as an input for the next step. |
| 152 | + 00 01 00 00 --> number obtained by right shift at step b) |
| 153 | +| 11 00 01 00 --> number obtained by left shift at step d) |
| 154 | + 11 01 01 00 |
| 155 | +
|
| 156 | +f) Assign the result into num after apply bitwise or into num again to proceed further |
| 157 | + num = 11010100 |
| 158 | +Till here, 2 of 3 steps of process has been completed. Only 1 more to go!!!!!!!!! |
| 159 | +
|
| 160 | +Divide obtained bits(11010100) into 1 - 1 each (1 * 8 = 8 bits) |
| 161 | +1|1|0|1|0|1|0|0 and swap with each other i.e. |
| 162 | + |_| |_| |_| |_| |
| 163 | +1|1|1|0|1|0|0|0 (It can also be said that we are right shifting 1st(1), 3rd(0), 5th(0) and 7th(0) parts to 1 place from their original positions and left shifting the 2nd(1), 4th(1), 6th(1) and 8th(0) parts to 1 place from their original positions) |
| 164 | +
|
| 165 | +Following is the process of doing it |
| 166 | +a) Preserve 1st(1), 3rd(0), 5th(0) and 7th(0) parts |
| 167 | +We know the property of bitwise and(&) operator i.e. 0, 1 -> 0 and 1, 1 -> 1 |
| 168 | +For this, we will take a mask in hexadecimal form and apply bitwise and(&) to preserve 1st(1), 3rd(0), 5th(0) and 7th(0) parts |
| 169 | +mask = 0xaa (which is nothing but 1010 1010 i.e. (10 == a) and (10 == a)) |
| 170 | + 1 1 0 1 0 1 0 0 --> num |
| 171 | +& 1 0 1 0 1 0 1 0 --> 0xaa |
| 172 | + 1 0 0 0 0 0 0 0 |
| 173 | +
|
| 174 | +b) Right shift the obtained number(1 0 0 0 0 0 0 0) from its original position by 1 place i.e. (num & 0xaa) >>> 1 |
| 175 | + 0 1 0 0 0 0 0 0 |
| 176 | +
|
| 177 | +c) Preserve the 2nd(1), 4th(1), 6th(1) and 8th(0) parts |
| 178 | +For this, we will take a mask in hexadecimal form and apply bitwise and(&) to preserve 2nd(1), 4th(1), 6th(1) and 8th(0) parts |
| 179 | +mask = 0x55 (which is nothing but 0101 0101 i.e. 0101(5) and 0101(5)) |
| 180 | + 1 1 0 1 0 1 0 0 --> num |
| 181 | +& 0 1 0 1 0 1 0 1 --> 0x55 |
| 182 | + 0 1 0 1 0 1 0 0 |
| 183 | +
|
| 184 | +d) Left shift the obtained number(0 1 0 1 0 1 0 0) from its original position by 1 place i.e. (num & 0x55) << 1 |
| 185 | + 1 0 1 0 1 0 0 0 |
| 186 | +
|
| 187 | +e) Do the bitwise OR(|) operation on both shifted numbers |
| 188 | + 0 1 0 0 0 0 0 0 --> number obtained by right shift at step b) |
| 189 | +| 1 0 1 0 1 0 0 0 --> number obtained by left shift at step d) |
| 190 | + 1 1 1 0 1 0 0 0 |
| 191 | +
|
| 192 | +f) Assign the result into num after apply bitwise or into num again |
| 193 | + num = 11101000 |
| 194 | +Now, return the num. |
| 195 | +
|
| 196 | +We have finally reversed the original number i.e. 00010111 -> 11101000 |
| 197 | +
|
| 198 | +
|
| 199 | +Same idea goes for 32 bits |
| 200 | +eg: |
| 201 | +break the 32 bits into half(16 - 16 each) and right shift 1st half part to 16 positions and left shift the 2nd half to 16 positions |
| 202 | +break the 16 bits into half(8 - 8 each) and right shift to 8 positions and left shift to 8 positions |
| 203 | +break the 8 bits into half(4 - 4 each) and right shift to 4 positions and left shift to 4 positions |
| 204 | +break the 4 bits into half(2 - 2 each) and right shift to 2 positions and left shift to 2 positions |
| 205 | +break the 2 bits into half(1 - 1 each) and right shift to 1 positions and left shift to 1 positions |
| 206 | +
|
| 207 | + */ |
| 208 | +} |
| 209 | + |
| 210 | +class B { |
| 211 | + // In this approach , First you will initialize result(k) with 0. |
| 212 | + // As we have 32 bits in 32 bit unsigned integer(n) so we can ran loop 32 times. In each iteration , |
| 213 | + // we will left shift one bit of our current result and then we do n&1 so that we can know that whether |
| 214 | + // we have 0 or 1 as first (right most ) bit . |
| 215 | + // Now we can update our result with the equation k=(k|(n&1)) and also we update our number(n) by right shifting of one bit of it . After 32 iteration we can find that we have result k as reversed bit of number n. |
| 216 | + int reverseBits(int nums) { |
| 217 | + int ans = 0; |
| 218 | + |
| 219 | + /// Getting the bits of the number. |
| 220 | + for (int i = 31; i >= 0; i--) { |
| 221 | + ans |= (nums & 1) << i; |
| 222 | + nums = nums >> 1; |
| 223 | + } |
| 224 | + return ans; |
| 225 | + } |
| 226 | +} |
| 227 | + |
| 228 | +class C { |
| 229 | + int reverseBits(int nums) { |
| 230 | + // List<int> bits = List.empty(growable: true); |
| 231 | + List<int> bits = []; |
| 232 | + |
| 233 | + /// Getting the bits of the number. |
| 234 | + for (int i = 0; i < 32; i++) { |
| 235 | + bits.add(nums & 1); |
| 236 | + nums = nums >> 1; |
| 237 | + } |
| 238 | + |
| 239 | + /// Reversing the bits. |
| 240 | + for (int x in bits) { |
| 241 | + nums = nums << 1; |
| 242 | + if (x == 0) { |
| 243 | + nums = nums | 1; |
| 244 | + } |
| 245 | + } |
| 246 | + |
| 247 | + return nums; |
| 248 | + } |
| 249 | +} |
0 commit comments