Skip to content

Commit e7a160c

Browse files
committed
leetcode
1 parent 900c412 commit e7a160c

File tree

4 files changed

+358
-0
lines changed

4 files changed

+358
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ This repo contain leetcode solution using DART and GO programming language. Most
6666
- [Excel Sheet Column Number](ExcelSheetColumnNumber/excel_sheet_colum_number.dart)
6767
- [Decode Ways](DecodeWays/decode_ways.dart)
6868
- [Number of 1 Bits](NumberOf-1-Bits/number_of_1_bits.dart)
69+
- [Reverse Bits](ReverseBits/reverse_bits.dart)
6970

7071
## Reach me via
7172

ReverseBits/reverse_bits.dart

+249
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
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+
}

ReverseBits/reverse_bits.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package main
2+
3+
// Runtime: 0 ms, faster than 100.00% of Go online submissions for Reverse Bits.
4+
// Memory Usage: 2.5 MB, less than 99.52% of Go online submissions for Reverse Bits.
5+
func reverseBits(num uint32) uint32 {
6+
num = (num >> 16) | (num << 16)
7+
num = ((num & 0xff00ff00) >> 8) | ((num & 0x00ff00ff) << 8)
8+
num = ((num & 0xf0f0f0f0) >> 4) | ((num & 0x0f0f0f0f) << 4)
9+
num = ((num & 0xcccccccc) >> 2) | ((num & 0x33333333) << 2)
10+
num = ((num & 0xaaaaaaaa) >> 1) | ((num & 0x55555555) << 1)
11+
return num
12+
}

ReverseBits/reverse_bits.md

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# 🔥 Reverse Bits 🔥 || 3 Solutions || Simple Fast and Easy || with Explanation
2+
3+
## Solution - 1 Divide and Conquer
4+
5+
```dart
6+
class Solution {
7+
// It reverses the bits of a 32-bit unsigned integer.
8+
// Args:
9+
// nums (int): 1010 1010 1010 1010 1010 1010 1010 1010
10+
//
11+
// Returns:
12+
// The number of bits that are different between two numbers.
13+
int reverseBits(int nums) {
14+
nums = ((nums & 0xffff0000) >>> 16) | ((nums & 0x0000ffff) << 16);
15+
nums = ((nums & 0xff00ff00) >>> 8) | ((nums & 0x00ff00ff) << 8);
16+
nums = ((nums & 0xf0f0f0f0) >>> 4) | ((nums & 0x0f0f0f0f) << 4);
17+
nums = ((nums & 0xcccccccc) >>> 2) | ((nums & 0x33333333) << 2);
18+
nums = ((nums & 0xaaaaaaaa) >>> 1) | ((nums & 0x55555555) << 1);
19+
20+
return nums;
21+
}
22+
```
23+
24+
## Solution - 2 - Bit Manipulation - Brute Force
25+
26+
In this approach , First you will initialize result(k) with 0.
27+
As we have 32 bits in 32 bit unsigned integer(n) so we can ran loop 32 times. In each iteration ,
28+
we will left shift one bit of our current result and then we do n&1 so that we can know that whether
29+
we have 0 or 1 as first (right most ) bit .
30+
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.
31+
32+
```dart
33+
class Solution {
34+
int reverseBits(int nums) {
35+
int ans = 0;
36+
37+
/// Getting the bits of the number.
38+
for (int i = 31; i >= 0; i--) {
39+
ans |= (nums & 1) << i;
40+
nums = nums >> 1;
41+
}
42+
return ans;
43+
}
44+
}
45+
```
46+
47+
## Solution - 3
48+
49+
- Store All bits in a List in reverse Manner
50+
- Add All bits to number
51+
52+
```dart
53+
class Solution {
54+
int reverseBits(int nums) {
55+
// List<int> bits = List.empty(growable: true);
56+
List<int> bits = [];
57+
58+
/// Getting the bits of the number.
59+
for (int i = 0; i < 32; i++) {
60+
bits.add(nums & 1);
61+
nums = nums >> 1;
62+
}
63+
64+
/// Reversing the bits.
65+
for (int x in bits) {
66+
nums = nums << 1;
67+
if (x == 0) {
68+
nums = nums | 1;
69+
}
70+
}
71+
72+
return nums;
73+
}
74+
}
75+
```
76+
77+
## Bonus Solution - Golang
78+
79+
```go
80+
// Runtime: 0 ms, faster than 100.00% of Go online submissions for Reverse Bits.
81+
// Memory Usage: 2.5 MB, less than 99.52% of Go online submissions for Reverse Bits.
82+
func reverseBits(num uint32) uint32 {
83+
num = (num >> 16) | (num << 16)
84+
num = ((num & 0xff00ff00) >> 8) | ((num & 0x00ff00ff) << 8)
85+
num = ((num & 0xf0f0f0f0) >> 4) | ((num & 0x0f0f0f0f) << 4)
86+
num = ((num & 0xcccccccc) >> 2) | ((num & 0x33333333) << 2)
87+
num = ((num & 0xaaaaaaaa) >> 1) | ((num & 0x55555555) << 1)
88+
return num
89+
}
90+
```
91+
92+
## Disclaimer:-
93+
94+
### This Solution is not available in DART Programing language with is a bummer. Hurts my feeling. But as a man we should implement it no matter what. We are not bunch of wussies who gonna skip it if it's not available in one language we love. Instead we will conquer the sea and rivers and cross the mountains so see what's lies beyond our horizons
95+
96+
## [GitHub Link](https://github.com/ayoubzulfiqar/leetcode)

0 commit comments

Comments
 (0)