You are on page 1of 37

12/8/21, 12:27 PM Untitled

Page 1

Page 2

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Chu Chu Chu Chu, this is a collection of the original thematic "Bitwise Operations" of the public account "Miyamizu Sanye 's Diary of Brushing Questions

The update time of this collection is 2021-10-07 , and itThe


willweekly
be updated
meeting
oncewill
every
be Note
updated
2-4 weeks.
the once.
official
Payaccount,
attention
thetobackground
the officialwill
account,
replyand
"Weiyun
reply "Weiyun
Calculate" to get the latest download link.

The followingBest
describes the best
practices practices
for using for using this collection
this collection:

Learning algorithm:

1. Open the online catalog ( Github version & Gitee version );


2. Find "Bitwise Operation" from the category list on the sidebar;
3. According to the "recommendation index" from large to small, the "recommendation index" is the same, then according to the "difficulty" from
Difficult to solve the problem'
4. After getting the question number, go back to this collection to search.

Maintain proficiency:

1. Follow this collection "from top to bottom" to refresh the questions.

If you encounter any difficulties, Welcome


in the learning
to joinprocess,
the "Onewelcome
Question
to Check-in
join the "Daily
QQ Group:
One 703311589 " for communication

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description

This is the 137. Number II on LeetCode that only appears once , and the difficulty is medium .

Tag: "Hash Table", "Bit Operation"

Give you an array of integers nums. Except for an element that appears only once, every other element appears exactly three times. Please find

Export and return the element that only appears once.

Example 1:

Input: nums = [2,2,3,2]

Output: 3

Page 3

Example 2:

Input: nums = [0,1,0,1,0,1,99]

Output: 99

https://translate.googleusercontent.com/translate_f 1/37
12/8/21, 12:27 PM Untitled

hint:

• 1 <= nums.length <= 3 * 10 4


• -2 31 <= nums[i] <= 2 31 -1
• In nums, except for an element that appears only once, every other element appears exactly three times

Advanced: Your algorithm should have linear time complexity. Can you do this without using extra space?

Hash table
A simple way is to use a "hash table" to count, and then output the number counted as 1 .

The hash table is stored in the form of "value: number of occurrences of a value".

Code:

class Solution {
public int singleNumber ( int [] nums) {
Map < Integer , Integer > map = new HashMap <>();
for ( int x : nums) {
map. put (x, map. getOrDefault (x, 0 ) + 1 );
}
for ( int x : map. keySet ()) {
if (map. get (x) == 1 ) return x;
}
return- 1 ;
}
}

• Time complexity: O ( n )
• Space complexity: O ( n )

Page 4

Digit statistics
The space complexity of the hash table solution is O ( n ) , and the [Advanced] part of the title mentions that it should be done with a constant space.

One of the easier ways to think of is to use the int type to be fixed to 32 bits.

Use an array of length 32 cnt [] to record each


Record
digit
howof all
many times 1 of each digit of all the values ​appear , and then check the cnt [] array
values
Operate
Each of them performs mod to re-assemble
3 operation the valueonly
and re-assembles thatout
only appears once.

For example, consider the example [1,1,1,3] . The binary representations of 1 and 3 are 00..001 and 00..011 , respectively .
Enter the cnt [] array and get [0,0,...,0,1,4] . After mod 3 operation, you get [0,0,...,0,1,1] , and then turn it into
You can get the answer "only once" by using decimal numbers . 3 .

Code:

class Solution {
public int singleNumber ( int [] nums) {
int [] cnt = new int [ 32 ];
for ( int x : nums) {
for ( int i = 0 ; i < 32 ; i ++ ) {

https://translate.googleusercontent.com/translate_f 2/37
12/8/21, 12:27 PM Untitled
if (((x >> i) & 1 ) == 1 ) {
cnt[i] ++ ;
}
}
}
int ans = 0 ;
for ( int i = 0 ; i < 32 ; i ++ ) {
if ((cnt[i] % 3 & 1 ) == 1 ) {
ans += ( 1 << i);
}
}
return ans;
}
}

• Time complexity: O ( n )
• Space complexity: O (1)

Page 5

DFA
If we consider the situation that "except for a certain element only appears once, every other element appears twice", then we can use
Use "exclusive OR" operation.

Using the property that the same number is exclusive or equal to 0 can help us achieve state switching well:

This question is to consider the situation that "except for a certain element only appears once, every other element appears three times", then it corresponds
The three states of "0 occurrences", "1 occurrences" and "2 occurrences" mean that at least two digits are required for recording, and the status
The state conversion relationship is:

https://translate.googleusercontent.com/translate_f 3/37
12/8/21, 12:27 PM Untitled

So how to express the above DFA with an expression? There are several methods:

1. Use the "truth table" to write the "logical function expression" can refer to here , the simplification process can refer to the Karnaugh map simp
Method .
2. Remember the conclusion (this is a classic DFA introductory question).

Page 6

3. Just do it hard, there are only those kinds of bit operations, you can't remember the "digital circuit" or remember the "conclusion", so you can
It is also possible to write the table continuously adjusting the logic.

Code:

class Solution {
public int singleNumber ( int [] nums) {
int one = 0 , two = 0 ;
for ( int x : nums){
one = one ^ x & ~ two;
two = two ^ x & ~ one;
}
return one;
}
}

• Time complexity: O ( n )
• Space complexity: O (1)

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description
This is the LeetCode 190. The inverted bit , the difficulty is simple .

Tag: "Bitwise Operation", "Analog"

Reverse the binary bits of a given 32-bit unsigned integer.

hint:

• Please note that in some languages ​(such as Java), there is no unsigned integer type. In this case, enter and
The output will be designated as a signed integer type, and should not affect your implementation, because regardless of whether the integer
The number is still unsigned, and the internal binary representation is the same.
• In Java, the compiler uses two's complement notation to represent signed integers. So in the example above
In 2, the input represents a signed integer -3, and the output represents a signed integer -1073741825.

Advanced:

Page 7

• If you call this function multiple times, how would you optimize your algorithm?

Example 1:

https://translate.googleusercontent.com/translate_f 4/37
12/8/21, 12:27 PM Untitled

Input: 00000010100101000001111010011100

Output: 00111001011110000010100101000000

Explanation: The input binary string 00000010100101000001111010011100 represents an unsigned integer 43261596,

Therefore, 964176192 is returned, and its binary representation is 00111001011110000010100101000000.

Example 2:

Input: 11111111111111111111111111111101

Output: 10111111111111111111111111111111
Explanation: The input binary string 11111111111111111111111111111101 represents an unsigned integer 4294967293,

Therefore, 3221225471 is returned and its binary representation is 10111111111111111111111111111111.

hint:

• The input is a binary string of length 32

"Symmetry" structure

A simple way is to check the input n .

Page 8

If one of the digits is 1 , then the corresponding symmetrical position of the answer is changed to 1 .

Code:

public class Solution {


public int reverseBits ( int n) {
int ans = 0 ;
for ( int i = 0 ; i < 32 ; i ++ ) {
int t = (n >> i) & 1 ;
if (t == 1 ) {
ans |= ( 1 << ( 31 - i));
}
}
return ans;
}
}

• Time complexity: int is fixed at 32 bits, and the number of cycles does not change with the input samples. Complexity is O (1)
• Space complexity: O (1)

https://translate.googleusercontent.com/translate_f 5/37
12/8/21, 12:27 PM Untitled

"Bit-by-bit separation" structure

Another approach is to use the lowest bit of n each time, use the lowest bit of n to update the lowest bit of the answer, use
After that, move n to the right by one place, and move the answer to the left by one place.

It is equivalent to updating the lowest bit of n to the lowest bit of ans every time .

Page 9

Code:

public class Solution {


public int reverseBits ( int n) {
int ans = 0 ;
int cnt = 32 ;
while (cnt -> 0 ) {
ans <<= 1 ;
ans += (n & 1 );
n >>= 1 ;
}
return ans;
}
}

• Time complexity: int is fixed at 32 bits, and the number of cycles does not change with the input samples. Complexity is O (1)
• Space complexity: O (1)

"Group swap"

https://translate.googleusercontent.com/translate_f 6/37
12/8/21, 12:27 PM Untitled

In fact, we can use the "group construction" method for int types with a fixed length .

Two - digit swap- > four-digit swap- > eight-digit swap- > 16-digit swap.

Code:

Page 10

public class Solution {


public int reverseBits ( int n) {
n = ((n & 0xAAAAAAAA ) >>> 1 ) | ((n & 0x55555555 ) << 1 );
n = ((n & 0xCCCCCCCC ) >>> 2 ) | ((n & 0x33333333 ) << 2 );
n = ((n & 0xF0F0F0F0 ) >>> 4 ) | ((n & 0x0F0F0F0F ) << 4 );
n = ((n & 0xFF00FF00 ) >>> 8 ) | ((n & 0x00FF00FF ) << 8 );
n = ((n & 0xFFFF0000 ) >>> 16 ) | ((n & 0x0000FFFF ) << 16 );
return n;
}
}

• Time complexity: How to perform the swap operation depends on the length of the int . Complexity is O (1)
• Space complexity: O (1)

PS. A similar approach me at 191. Bit 1 number is alsopass.


introduced. If you
If you can learncan learnI suggest
more, more you simulate it on paper
Take a look at this process. If you don’t want to go deep, you can also use it as a template to memorize (the writing is very fixed).
But please don't think
"Method
that 3"
"Method
must be3"faster
mustthan
be faster
"Method
than 1"
"Method
and other
1" and
methods
otherthat
methods
directly
thatuse
directly
loops.use
Theloops.
biggest
The
work
biggest
of this
work
type
ofof
this
approach
type of approach
Use, not to deal with int , but to deal with the case of larger digits. In the case of int with a length of only 32 bits , this approach is not necessarily
It is faster than a loop (this approach will produce multiple intermediate
The value
results,
occurs
resulting
multiple
in multiple
times, and
assignments,
because there
and due
is a to
pair
then existence
between instructions
of pairs of instru
Numerical dependence may not be optimized
Parallel instruction),
as a parallelthis
instruction),
reason andthis
forreason
the case
andoffor
fewer
the case
sorting
of fewer
elements,
sorting
we will
elements,
chooseI
"Bubble sort" instead of "merge
"Merge sort"
sort" is
is the
the same,
same, because
because theThe
"bubble
"bubble
sort"sort"
constant
constant
is smaller.
is smaller.

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description

This is the LeetCode 191. The bit 1 number , the difficulty is simple .

Tag: "Bit Operation"

Write a function, the input is an unsigned integer (in the form of a binary string), return the number of digits in the binary expression
It is the number of '1' (also known as Hamming weight).

hint:

• Please note that in some languages ​(such as Java), there is no unsigned integer type. In this case, enter and
The output will be designated as a signed integer type, and should not affect your implementation, because regardless of whether the integer
The number is still unsigned, and the internal binary representation is the same.

Page 11

• In Java, the compiler uses two's complement notation to represent signed integers. So in the example above

https://translate.googleusercontent.com/translate_f 7/37
12/8/21, 12:27 PM Untitled

In 3, the input represents a signed integer -3.

Example 1:

Input: 00000000000000000000000000001011

Output: 3
Explanation: In the input binary string 00000000000000000000000000001011, a total of three bits are '1'.

Example 2:

Input: 00000000000000000000000010000000
Output: 1

Explanation: In the input binary string 00000000000000000000000010000000, a total of one bit is '1'.

Example 3:

Input: 11111111111111111111111111111101
Output: 31
Explanation: In the input binary string 11111111111111111111111111111101, a total of 31 bits are '1'.

hint:

• The input must be a binary string of length 32.

Advanced:

• If you call this function multiple times, how would you optimize your algorithm?

"Digit check" solution


A simple way is to check each digit of int and count the number of 1 .

Page 12

https://translate.googleusercontent.com/translate_f 8/37
12/8/21, 12:27 PM Untitled
Code:

public class Solution {


public int hammingWeight ( int n) {
int ans = 0 ;
for ( int i = 0 ; i < 32 ; i ++ ) {
ans += ((n >> i) & 1 );
}
return ans;
}
}

• Time complexity: O ( k ) , k is the number of int bits, fixed to 32 bits


• Space complexity: O (1)

"Right shift statistics" solution


For method 1, even if the high bits of n are all 0 , we will perform a loop check on this.

Therefore, another method is to use n & 1 to count whether the lowest bit of n is 1 , and at the same time directly perform a calculation on n each time
Shift right and fill 0 in high bits.

When n = 0 means , we have completed all 1 statistics.

Page 13

This approach can ensure that only the highest 1 is looped .

Code:

public class Solution {


public int hammingWeight ( int n) {
int ans = 0 ;
while (n != 0 ) {
ans += (n & 1 );
n >>>= 1 ;
}
return ans;
}
}

• Time complexity: O ( k ) , k is the number of int bits, fixed to 32 bits, and the worst-case binary representation of n

https://translate.googleusercontent.com/translate_f 9/37
12/8/21, 12:27 PM Untitled
All 1
• Space complexity: O (1)

" Lowbit " solution


For method 2, if the highest bit 1 and the lowest bit 1 are all 0s , we will still shift right several times until the highest bit is processed.
Up to 1 .

Page 14

So is there a way to process only the binary digits with a digit of 1 ?

It can be done using lowbit . Lowbit will return the number represented by the lowest bit 1 in the binary representation within O (1) complexity.
value.

For example (0000 ... 111100) 2 incoming lowbit return (0000 ... 000100) ;2(0000...00011) 2 incoming
lowbit returns (0000...00001) 2 …

Code:

public class Solution {


public int hammingWeight ( int n) {
int ans = 0 ;
for ( int i = n; i != 0 ; i -= lowbit (i)) ans ++ ;
return ans;
}
int lowbit ( int x) {
return x & -x;
}
}

• Time complexity: O ( k ) , k is the number of int bits, fixed to 32 bits, and the worst-case binary representation of n
All 1
• Space complexity: O (1)

Page 15

https://translate.googleusercontent.com/translate_f 10/37
12/8/21, 12:27 PM Untitled

"Group Statistics" Solution


The above three solutions are all O ( k ) . In fact, we can achieve lower complexity than O ( k ) by grouping statistics
Spend.

Code:

public class Solution {


public int hammingWeight ( int n) {
n = (n & 0x55555555 ) + ((n >>> 1 ) & 0x55555555 );
n = (n & 0x33333333 ) + ((n >>> 2 ) & 0x33333333 );
n = (n & 0x0f0f0f0f ) + ((n >>> 4 ) & 0x0f0f0f0f );
n = (n & 0x00ff00ff ) + ((n >>> 8 ) & 0x00ff00ff );
n = (n & 0x0000ffff ) + ((n >>> 16 ) & 0x0000ffff );
return n;
}
}

• Time complexity: O (log k ) , k is the number of int bits, fixed to 32 bits


• Space complexity: O (1)

PS. For this solution, if you can learn more, I suggest you simulate this process on paper. If you don't want to be deep
It can also be used as a template to memorize (the writing method is very fixed), but usually if you are not writing the underlying framework, you will almo
An O (log k ) solution case.

And the biggest effect of this approach is not to deal with int , but to deal with the case of larger digits, in the case of only 32 bits in length

Page 16

In the case of int , this approach is not necessarily faster than the loop (this approach will produce multiple intermediate results, resulting in more assignmen
Time, and due to the dependence on the value of n between the instructions , it may not be optimized as a parallel instruction).
When there are few sequence elements, we will choose "selection sort" instead of "merge sort", which is the same.

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description

This is the LeetCode 231. The 2 powers , the difficulty is simple .

Tag: "mathematics", "bit operation"

https://translate.googleusercontent.com/translate_f 11/37
12/8/21, 12:27 PM Untitled

Give you an integer n, please judge whether the integer is a power of 2. If yes, return true; otherwise, return false.

If there is an integer x such that n == 2 x , then n is considered a power of 2.

Example 1:

Input: n = 1
Output: true
Explanation: 20 = 1

Example 2:

Input: n = 16
Output: true
Explanation: 24 = 16

Example 3:

Input: n = 3

Output: false

Example 4:

Input: n = 4
Output: true

Page 17

Example 5:

Input: n = 5
Output: false

hint:

• -2 31 <= n <= 2 31 -1

Advanced: Can you solve this problem without using loop/recursion?

Plain approach
First of all , numbers less than or equal to 0 must not be, but 1 must be.

After processing these boundaries try n cleaned with, if the value of the last remaining . 1 is illustrated initially two powers.

Code:

class Solution {
public boolean isPowerOfTwo ( int n) {
if (n <= 0 ) return false ;
while (n % 2 == 0 ) n /= 2 ;
return n == 1 ;
}
}

• Time complexity: O (log n )


https://translate.googleusercontent.com/translate_f 12/37
12/8/21, 12:27 PM Untitled

• Space complexity: O (1)

lowbit
Students who are familiar with tree arrays know that lowbit can quickly find the value represented by the lowest bit 1 in the binary representation of x .

If a number n is a power of 2 , then it has the property of lowbit(n) = n ( the binary representation of a power of 2 must be the highest
The bit is 1 , the low bit is 0 ).

Page 18

Code;

class Solution {
public boolean isPowerOfTwo ( int n) {
return n > 0 && (n & -n) == n;
}
}

• Time complexity: O (1)


• Space complexity: O (1)

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description

This is the LeetCode 342. The 4 powers , the difficulty is simple .

Tag: "mathematics", "bit operation"

Given an integer, write a function to determine whether it is a power of 4. If yes, return true; otherwise, return false

If the integer n is a power of 4, it must satisfy: there is an integer x such that n == 4 x

Example 1:

Input: n = 16
Output: true

Example 2:

Input: n = 5
Output: false

Example 3:

https://translate.googleusercontent.com/translate_f 13/37
12/8/21, 12:27 PM Untitled
Page 19

Input: n = 1
Output: true

hint:

• -2 31 <= n <= 2 31 -1

Advanced:

Can you complete this problem without using loops or recursion?

Fundamental analysis
If a number n is a power of 4 , it is equivalent to n being a prime factor and only a square number of 2 .

Therefore, we can convert the problem: to determine whether n is a power of 2 .

The analysis to determine whether a certain number is a power of 2 is in (Solution) 231.2 Powers here.

sqrt + lowbit

We can execute the sqrt function on n first , and then use the lowbit function to quickly determine whether n is a power of 2 .

Code:

class Solution {
public boolean isPowerOfFour ( int n) {
if (n <= 0 ) return false ;
int x = ( int ) Math . sqrt (n);
return x * x == n && (x & -x) == x;
}
}

Page 20

class Solution {
public boolean isPowerOfFour ( int n) {
if (n <= 0 ) return false ;
int x = getVal (n);
return x * x == n && (x & -x) == x;
}
int getVal ( int n) {
long l = 0 , r = n;
while (l < r) {
long mid = l + r >> 1 ;
if (mid * mid >= n) {
r = mid;
} else {
l = mid + 1 ;

https://translate.googleusercontent.com/translate_f 14/37
12/8/21, 12:27 PM Untitled
}
}
return ( int )r;
}
}

• Time complexity: The complexity depends on the built-in function sqrt . A simple sqrt implementation is close to P2

Code. The complexity is O (log n )


• Space complexity: O (1)

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description
This is the sum of 371. two integers on LeetCode, and the difficulty is medium .

Tag: "Bit Operation"

Give you two integers a and b , without using the operators + and - , calculate and return the sum of the two integers.

Example 1:

Input: a = 1, b = 2

Output: 3

Page 21

Example 2:

Input: a = 2, b = 3

Output: 5
```

hint:
* -1000 <= a, b <= 1000

---

### Bit operation

<p class="mume-header "id="bit operation"></p>

A simple method is to use "bit operation", using the binary "every two into one" and "`int` binary representation length is $32$", we can process from low to high, and use it in the process

Then discuss the current position of the two numbers:

* Both current bits are $1$: What the current bit is depends on the carry situation of the previous one, that is, `ans |= (t << i)`, and carry $t = 1$ at the same time;
* Only one of the two current digits is $1$: What the current digit is depends on the carry situation of the previous digit (it can be unified as `ans |= ((1 ^ t) << i)`:
* If the previous carry is $1$, combined with this digit is $1$, then the current digit is $0$, and the carry remains unchanged $t = 1$;
* If the previous carry is $0$, combined with this digit is $1$, then the current digit is $1$, and the carry remains unchanged $t = 0$;
* The two current bits are $0$: at this time, what the current bit is depends on the carry situation of the previous one, so `ans |= (t << i)`, and carry $t = 0$ at the same time.

Code:
```Java

class Solution {
public int getSum(int a, int b) {

int ans = 0;

https://translate.googleusercontent.com/translate_f 15/37
12/8/21, 12:27 PM Untitled
for (int i = 0, t = 0; i <32; i++) {
int u1 = (a >> i) & 1, u2 = (b >> i) & 1;
if (u1 == 1 && u2 == 1) {
ans |= (t << i);
t = 1;
} else if (u1 == 1 || u2 == 1) {
ans |= ((1 ^ t) << i);
} else {
ans |= (t << i);
t = 0;
}

}
return ans;
}
}

Page 22

• Time complexity: O ( C ) , C is a constant, fixed at 32


• Space complexity: O (1)

Recursion
After a thorough understanding of "Solution One", it is not difficult to find that the essence of "Solution One" is to "split" the current position of the two nu

First calculate the result of the original a and the original b without considering the carry, the result is a ^ b , and then on this basis,
Consider adding the carry in, and the accumulation operation can be processed recursively using getSum .

The problem is transformed into how to find the carry value of a and b .

It is not difficult to find that if and only if the current bits of a and b are both 1 , there is a carry in this bit, and the carry back is applied to the current bit.
One bit (on the left side, one bit higher), so the final carry result is (a & b) << 1 .

Therefore, we can get the final answer by calling getSum(a ^ b, (a & b) << 1) recursively .

Finally, consider when the splitting process will end.

Since there is a left shift operation in the carry result (a & b) << 1 , so after performing a maximum of 32 recursive operations, the value
Will become 0 , and the result of adding 0 to any value x is x .

Code:

class Solution {
public int getSum ( int a, int b) {
return b == 0 ? a : getSum (a ^ b, (a & b) << 1 );
}
}

• Time complexity: Let C be a constant, fixed to 32 , execute (a & b) << 1 at most C times , recursively
The end of the journey. The complexity is O ( C )
• Space complexity: O (1)

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

https://translate.googleusercontent.com/translate_f 16/37
12/8/21, 12:27 PM Untitled

Page 23

Title description
This is the LeetCode 405. The number is converted to a hexadecimal number , the difficulty is simple .

Tag: "Bitwise Operation", "Analog"

Given an integer, write an algorithm to convert this number into a hexadecimal number. For negative integers, we usually use one's complement

Calculating method.

Notice:

1. All letters (af) in the hexadecimal system must be lowercase.


2. No extra leading zeros can be included in the hexadecimal string. If the number to be converted is 0, then use a single word
Character '0'; for other cases, the first character in the hexadecimal string will not be a 0 character.
3. The given number is guaranteed to be within the 32-bit signed integer range.
4. Do not use any method provided by the library to directly convert or format numbers into hexadecimal.

Example 1:

Input: 26

Output: "1a"

Example 2:

Input: -1

Output: "ffffffff"

Analog + hexadecimal conversion


First of all, we can make use of the general idea of ​hexadecimal conversion, continuously looping num% k and num / k operations to construct
Output each digit of the k base.

Thefirst
But we need to deal with the "complement code" problem: for negative num , we need to add 2 32 to num offset,
Then carry out the hexadecimal conversion.

Code:

Page 24

class Solution {
public String toHex ( int _num) {
if (_num == 0 ) return "0" ;
long num = _num;
StringBuilder sb = new StringBuilder ();
if (num < 0 ) num = ( long )( Math . pow ( 2 , 32 ) + num);
while (num != 0 ) {
long u = num % 16 ;
char c = ( char )(u + '0' );
if (u >= 10 ) c = ( char )(u - 10 + 'a' );
sb. append (c);

https://translate.googleusercontent.com/translate_f 17/37
12/8/21, 12:27 PM Untitled
num /= 16 ;
}
return sb. reverse (). toString ();
}
}

• Time complexity: The complexity depends on the length of the constructed hexadecimal number and is fixed at C = 8 . Overall complexity
Is O ( C )
• Space complexity: The complexity depends on the length of the constructed hexadecimal number and is fixed at C = 8 . Overall complexity
Is O ( C )

Bit operation + group conversion


The length 32 of the convert binary to 16 hexadecimal, is essentially a length of 32 grouping of binary numbers, each . 4 one-
Group (binary (1111) 2 Represents 15 , then use a binary length of 4 to represent 0-15 ).

At the same time, since we are directly grouping and converting the binary with a length of 32 ( 4 groups are a group, a total of 8 groups), and the length is
The binary of 32 itself is represented by the complement rule, so we don't need to deal with the "complement" problem.

Specifically, we perform & operation on num and 15 = (1111) 2 , and then unsigned right shift of num by 4 bits to realize
Now every 4 bits are processed.

Code:

Page 25

class Solution {
public String toHex ( int num) {
if (num == 0 ) return "0" ;
StringBuilder sb = new StringBuilder ();
while (num != 0 ) {
int u = num & 15 ;
char c = ( char )(u + '0' );
if (u >= 10 ) c = ( char )(u - 10 + 'a' );
sb. append (c);
num >>>= 4 ;
}
return sb. reverse (). toString ();
}
}

• Time complexity: The complexity depends on the length of the constructed hexadecimal number and is fixed at C = 8 . Overall complexity
Is O ( C )
• Space complexity: The complexity depends on the length of the constructed hexadecimal number and is fixed at C = 8 . Overall complexity
Is O ( C )

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description

https://translate.googleusercontent.com/translate_f 18/37
12/8/21, 12:27 PM Untitled
This is the LeetCode 461. The Hamming distance , the difficulty is simple .

Tag: "Bit Operation"

The Hamming distance between two integers refers to the number of positions where the two numbers correspond to different binary digits.

Given two integers x and y, calculate the Hamming distance between them.

Notice:
0 ≤ x, y <231.

Example:

Page 26

Input: x = 1, y = 4

Output: 2

explain:
1 (0 0 0 1)
4 (0 1 0 0)
↑↑

The arrows above point out the different positions of the corresponding binary bits.

Bit by bit comparison


It does not change x and y , and compares different offset bits each time, and adds one if they are different.

The cycle is fixed to full 32 .

Code:

https://translate.googleusercontent.com/translate_f 19/37
12/8/21, 12:27 PM Untitled

Page 27

class Solution {
public int hammingDistance ( int x, int y) {
int ans = 0 ;
for ( int i = 0 ; i < 32 ; i ++ ) {
int a = (x >> i) & 1 , b = (y >> i) & 1 ;
ans += a != b ? 1 : 0 ;
}
return ans;
}
}

• Time complexity: O ( C ) , C is fixed at 32


• Space complexity: O (1)

Right shift statistics


The last digit of the current x and y is counted every time, and x and y are shifted one digit to the right after counting .

When both the top 1 of x and y are counted, the loop ends.

Code:

Page 28

class Solution {
public int hammingDistance ( int x, int y) {
int ans = 0 ;
while ((x | y) != 0 ) {
int a = x & 1 , b = y & 1 ;
ans += a ^ b;
x >>= 1 ; y >>= 1 ;
}
return ans;

https://translate.googleusercontent.com/translate_f 20/37
12/8/21, 12:27 PM Untitled
}
}

• Time complexity: O ( C ) , C up to 32
• Space complexity: O (1)

lowbit

Students who are familiar with tree arrays know that lowbit can quickly find the value represented by the lowest bit 1 in the binary representation of x .

Therefore, we can X and Y first , and then count the number of 1s in the XOR result .

Code:

Page 29

class Solution {
int lowbit ( int x) {
return x & -x;
}
public int hammingDistance ( int x, int y) {
int ans = 0 ;
for ( int i = x ^ y; i > 0 ; i -= lowbit (i)) ans ++ ;
return ans;
}
}

• Time complexity: O ( C ) , C up to 32
• Space complexity: O (1)

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description

This is the sum of 477. Hamming distance on LeetCode , and the difficulty is medium .

Tag: "Bitwise Operation", "Mathematics"

https://translate.googleusercontent.com/translate_f 21/37
12/8/21, 12:27 PM Untitled
The Hamming distance of two integers refers to the number of different bits corresponding to the binary numbers of the two numbers.

Give you an integer array nums, please calculate and return the sum of the Hamming distance between any two numbers in nums.

Example 1:

Input: nums = [4,14,2]


Output: 6
Explanation: In binary representation, 4 is 0100, 14 is 1110, and 2 is 0010. (This expression is to reflect the relationship between the last four)
So the answer is:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6

Example 2:

Input: nums = [4,14,4]


Output: 4

Page 30

hint:

1 <= nums.length <= $10^5$


0 <= nums[i] <= $10^9$

Bitwise statistics
We know that the Hamming distance is the number of different bits in the binary representation of two numbers, and the statistics of each bit are independen

31
That is, the final answer is ∑ calc
x =0 ( x ) , where the calc function is generated by finding a certain bit of x in the binary representation of all numbers
The number of different bits.

We consider how a certain cacl ( x ) can be obtained:

In fact, for a certain nums[i], we only care about how many numbers in nums are different from the xth position, and do not care about
Which numbers are different from it, and the binary representation is not 0 or 1 .

This guides us to create two sets s 0 and s 1 , and count the number of 0 and 1 in the xth position of all the numbers in nums , respectively.
Number,
The eachof,time
number eachincount
the setin the set represents a certain element in nums , and the xth position is represented according to the difference in the set
Value. Then to find out how many numbers in nums are different from the x - th position of a certain number , you only need to read another set of
The number of elements is sufficient, and it becomes an O (1) operation. Then the number of logarithms of "all distinct numbers in the xth position" is req
Apply thethe
Using principle of of
principle multiplication to multiply
multiplication, the number
just multiply of elements
the number of theoftwo.
of elements the two.

https://translate.googleusercontent.com/translate_f 22/37
12/8/21, 12:27 PM Untitled

Page 31

As mentioned earlier, the statistics of each person are relatively independent, so as long as the above operations are applied to "each bit", and the "each bit"
The cumulative result is the final answer.

Code:

Page 32

class Solution {
public int totalHammingDistance ( int [] nums) {
int ans = 0 ;
for ( int x = 31 ; x >= 0 ; x - ) {
int s0 = 0 , s1 = 0 ;
for ( int u : nums) {
if (((u >> x) & 1 ) == 1 ) {

https://translate.googleusercontent.com/translate_f 23/37
12/8/21, 12:27 PM Untitled
s1 ++ ;
} else {
s0 ++ ;
}
}
ans += s0 * s1;
}
return ans;
}
}

• Time complexity: O ( C ∗ n ) , C is fixed at 32


• Space complexity: O (1)

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description

This is a beautiful arrangement of 526. On LeetCode , the difficulty is medium .

Tag: "Bitwise Operation", "Dynamic DP", "Dynamic Programming"

Suppose there are from 1 to N of N integers, if this N digital successfully constructed an array, the array so that the first i
Bit ( 1 <= i <= N ) satisfies one of the following two conditions, we call this array a beautiful arrangement.

condition:

• The i - th digit can be divisible by i


• i can be divisible by the number in the i - th place

Now given an integer N , how many beautiful permutations can be constructed?

Example 1:

Page 33

Input: 2

Output: 2

explain:
The first beautiful arrangement is [1, 2]:

The number in the first position (i=1) is 1, and 1 can be divisible by i (i=1)
The number in the second position (i=2) is 2, 2 can be divisible by i (i=2)

The second beautiful arrangement is [2, 1]:


The number in the first position (i=1) is 2, and 2 can be divisible by i (i=1)
The number in the second position (i=2) is 1, and i (i=2) can be divisible by 1

illustrate:

• N is a positive integer and will not exceed 15.

State compression DP
With the data range not exceeding 15 , we can use "State Compression DP" to solve.

https://translate.googleusercontent.com/translate_f 24/37
12/8/21, 12:27 PM Untitled

Use a binary number


The number
to indicate
system
which
indicates
numberswhich
have numbers
been selected
have and
beenwhich
selected
numbers
and which
have numbers
not been have
selected.
not been
The purpose
selected.isThe purpose is to use bit oper
speed.

We can get a feel for what "state compression" means through a specific example:

For example, (000...0101) 2 means that the number with the value 1 and the value 3 has been used, and the node with the value 2 has not been used.

Then let's take a look at how to perform some basic operations when using "state compression":

Assuming that the variable state stores the "usage of the current number", when we need to check whether the number k is used, we can
Bit arithmetic using a = (state >> k) & 1 , to obtain the state of the k -bit binary representation, if a is 1
The number representing k has been used, and if it is 0, it has not been accessed.

Define f [ i ][ state ] to consider the number of the first i , and the current selection plan is the number of all programs in the state .

An obvious initialization condition is f [0][0] = 1 , which means that when we do not consider any number ( i = 0 ), a number
Neither is selected ( state = 0 ) is a legal scheme.

Without loss of general considerations , how to transfer f [ i ][ state ] , since this question is to find the number of solutions, our transfer equation must be

Page 34

"Don't miss it."

We can enumerate which number is selected for the current position i . Assuming that the selected value for position i is k , first the k value needs to be sati
The following two conditions:

• The k - th bit in state is 1 ;


• Either k can be divisible by i , or i can be divisible by k .

Then according to the state definition, the value k is selected for position i . Through bit operation, we can directly get that the state before the decision pos
What: state &(¬(1 << ( k − 1))) , which means that the k-th position in the binary representation of state is 0 .

The final f [ i ] [ state ] selected for the current position i is the sum of the number of schemes with all legal k values:

n

f [ i ][ state ] = f [ i − 1][ state &(¬(1 << ( k − 1)))]
k =1

Some details: Since the given value range is [1, n ] , but for convenience in implementation, we use state from right to left
The 0th bit represents the selection of value 1 , and the 1st bit represents the selection of value 2 ... That is to make a choice for the value k
−1 offset.

Code:

https://translate.googleusercontent.com/translate_f 25/37
12/8/21, 12:27 PM Untitled

Page 35

class Solution {
public int countArrangement ( int n) {
int mask = 1 << n;
int [][] f = new int [n + 1 ][mask];
f[ 0 ][ 0 ] = 1 ;
for ( int i = 1 ; i <= n; i ++ ) {
// enumerate all states
for ( int state = 0 ; state < mask; state ++ ) {
// The selected value of the enumeration position i (the last digit) is k
for ( int k = 1 ; k <= n; k ++ ) {
// First, k must be 1 in state
if (((state >> (k - 1 )) & 1 ) == 0 ) continue ;
// The value k and the position i satisfy any divisible relationship
if (k % i != 0 && i % k != 0 ) continue ;
// state & (~(1 << (k-1))) represents zeroing the position of the value k in state
f[i][state] += f[i - 1 ][state & ( ~ ( 1 << (k - 1 )))];
}
}
}
return f[n][mask - 1 ];
}
}

• Time complexity: a total of n ∗ 2 n states need to be transferred, and the complexity of each transfer is O ( n ) , the overall complexity
2∗ 2 n)
Degree O ( n
• Space complexity: O ( n ∗ 2 n )

State compression DP (optimized)


Through the analysis of the simple state pressure DP, we found that when making the i - th position, in theory, the number of numbers we should use
The amount should also be i .

But this point is not reflected in the simple pressure DP, which leads us to decide the i - th place, we still need to
The state of is calculated and checked (even if the number of occurrences of 1 in the binary representation is not i ).

So we can enumerate in another way (using the new state definition and optimize the transition equation).

Define f [ state ] as the number of all solutions when the current selection value is state .

In this way, there is still an initialization condition of f [0] = 1 , and the final answer is f [(1 << n ) − 1] .

Page 36

Without loss of generality, consider how f [ state ] is calculated:

Starting from the current state state , check each bit 1 in the state as the last selected value, so that it is still
ensure
It can be that that
ensured the number of schemes
the number is “not
of schemes repetitive
is counted and notrepetition
"without missing”.and leakage". At the same time, since we enumerate the state "from small to la

https://translate.googleusercontent.com/translate_f 26/37
12/8/21, 12:27 PM Untitled
The other state values ​on which the calculation of f [ state ] depends must have already been calculated.

Similarly, we still need to make sure that the one in the state as the last 1 needs to be divisible by the position where it is placed.
Tie.

Therefore, we need a method to calculate the number of 1s in state , which can be implemented using lowbit here .

The final f [ state ] selected for the current position is the sum of the number of schemes with all legal values:

n

f [ state ] = f [ state &(¬(1 << i ))]
i =0

Code:

Page 37

class Solution {
int getCnt ( int x) {
int ans = 0 ;
while (x != 0 ) {
x -= (x & -x); // lowbit
ans ++ ;
}
return ans;
}
public int countArrangement ( int n) {
int mask = 1 << n;
int [] f = new int [mask];
f[ 0 ] = 1 ;
// enumerate all states
for ( int state = 1 ; state < mask; state ++ ) {
// Calculate how many 1s are in the state (that is, what is the current sort length)
int cnt = getCnt (state);
// What is the last digit of the enumeration
for ( int i = 0 ; i < n; i ++ ) {
// The value must be 1 in state
if (((state >> i) & 1 ) == 0 ) continue ;
// The value (i + 1) and the position (cnt) satisfy any divisible relationship

https://translate.googleusercontent.com/translate_f 27/37
12/8/21, 12:27 PM Untitled
if ((i + 1 ) % cnt != 0 && cnt % (i + 1 ) != 0 ) continue ;
// state & (~(1 << i)) represents zeroing the position of the selected value in state
f[state] += f[state & ( ~ ( 1 << i))];
}
}
return f[mask - 1 ];
}
}

• Time complexity: A total of 2 n states need to be transferred, and the complexity of each transfer is O ( n ) , and the overall complexity is
O(n∗2n)
• Space complexity: O (2 n )

Summarize
It is not difficult to find that the idea of ​compressing DP in the two states is actually exactly the same.

It’s just that in the plain pressure DP, we explicitly enumerate the case of considering each length (there is dimension i ), and in the case of pressure
In DP (optimization), the length information contained in the number of 1s in the state is used .

Page 38

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description
This is 1178. Word guessing puzzle on LeetCode . The difficulty is difficult .

Tag: "State Compression", "Bit Operation", "Hash Table"

Foreign friends have designed an English version of a word guessing game based on Chinese word puzzles. Please come and guess.

The puzzle of an anagram is given in the form of a string, if a word word meets the following two conditions, then it can
Counted as the answer:

• The word word contains the first letter of the puzzle.


• Every letter in the word word can be found in the puzzle.
For example, if the face of an anagram is "abcdefg", then the word that can be used as the answer is "faced",
"Cabbage", and "baggage"; and "beefed" (without the letter "a") and "based" (the
"S" does not appear in the mystery) can not be used as the answer to the mystery.

Return an answer array answer, each element in the array answer[i] can be used in the given word list words
It is the number of words corresponding to puzzles[i].

Example:

enter:
words = ["aaaa","asas","able","ability","actt","actor","access"],
puzzles = ["aboveyz","abrodyz","abslute","absoryz","actresz","gaswxyz"]

Output: [1,1,3,2,4,0]
explain:
One word can be used as the answer to "aboveyz": "aaaa"
One word can be used as the answer to "abrodyz": "aaaa"
Three words can be used as the answer to "abslute": "aaaa", "asas", "able"
Two words can be used as the answer to "absoryz": "aaaa", "asas"
4 words can be used as the answer to "actresz": "aaaa", "asas", "actt", "access"

https://translate.googleusercontent.com/translate_f 28/37
12/8/21, 12:27 PM Untitled
No word can be used as the answer to "gaswxyz", because the words in the list do not contain the letter'g'.

hint:

• 1 <= words.length <= 10 5

Page 39

• 4 <= words[i].length <= 50

• 1 <= puzzles.length <= 10 4


• puzzles[i].length == 7
• words[i][j], puzzles[i][j] are all lowercase English letters.
• The characters contained in each puzzle[i] are not repeated.

Naive bitwise arithmetic solution (TLE)


According to the corresponding conditions of "mystery" and "mystery face":

• The word word contains the first letter of the puzzle .


• word word of each letter can riddle puzzle found in the

The puzzle itself is only 7 digits long and does not repeat; we can find that the corresponding conditions have nothing to do with the repeated letters of the wo

So we can use "binary" numbers to represent each word and puzzle :

A binary number with a length of 26 to represent (directly use an int with a length of 32, use the lower 26 bits), if there is
str = "abz" corresponds to 100...011 (a total of 26 digits, from right to left are a-z).

At this point we can already come up with a naive solution idea:

1. Preprocessing except for all the binary digits corresponding to the word . The calculated amount
, The order is 50 * 10
of magnitude is 10
5 6
2. Make conditional judgments for each puzzle (each puzzle needs to traverse all words to check

* 10 is
check). The calculated amount 4, 10
The5order of magnitude is 10 9

The amount of calculation per second of the


Around computer
(OJ 10 7 10 6
tester isisusually ~ 10 7 Between), even after ignoring the constant, we
The total calculations of has exceeded the upper limit and will definitely time out.

Code:

Page 40

class Solution {
public List < Integer > findNumOfValidWords ( String [] ws, String [] ps) {

https://translate.googleusercontent.com/translate_f 29/37
12/8/21, 12:27 PM Untitled
// Preprocess
List < Integerthe binary
> list values
= new ​corresponding
ArrayList <>(); to all words

for ( String w : ws) list. add ( getBin (w));


// Determine how many answers each puzzle has
List < Integer > ans = new ArrayList <>();
for ( String p : ps) ans. add ( getCnt (list, p));
return ans;
}
// Determine how many answers a puzzle has
int getCnt ( List < Integer > ws, String str) {
int ans = 0 ;
// Get the binary number corresponding to the current puzzles
int t = getBin (str);
// The position of the first character of the current puzzles in the binary value
int first = str. charAt ( 0 ) - 'a' ;
for ( int w : ws) {
// check condition 1: the word word contains the first letter of the puzzle
if ((w >> first & 1 ) == 0 ) continue ;
// check condition two: every letter in the word word can be found in the puzzle
if ((w & t) == w) ans ++ ;
}
return ans;
}
// The letters contained in str are identified by binary
// If str = abz, the corresponding binary is 100...011 (26 bits in total, a-z from right to left)
int getBin ( String str) {
int t = 0 ;
char [] cs = str. toCharArray ();
for ( char c : cs) {
// Which one of the binary digits corresponds to each character
int u = c - 'a' ;
// If the current position is 0, it means that it has not been recorded yet, then record (not repeat record)
if ((t >> u & 1 ) == 0 ) t += 1 << u;
}
return t;
}
}

• Time complexity: O ( words . Length ∗ ( words [ i ]. length + puzzles . Length ))


• Space complexity: each word corresponds to an int, and each puzzle corresponds to an answer. the complexity
Is O ( words . Length + puzzles . Length )

Page 41

Hash table & bit operation solution


Therefore, we need to optimize the above step 1 or step 2. Obviously, the main reason for the timeout is too much calculation in step 2.

A very conspicuous breakthrough is to use puzzles[i].length == 7 , and at the same time determine that condition 1 is the first letter of puzzle
Qualified.

For a certain puzzle , we need to find out how many "mysteries" it has. It can be enumerated by all possible
"Mystery", and then go to words to find out how many times each "mystery" has appeared.

Combining the meaning of the question is to fix the first position of the puzzle and enumerate all the possibilities of the remaining 6 digits (each one

There are two choices


options:of
reserved
retention
andand
non-reserved
non-retention), that is, the process of enumerating subsets.

You may still not understand, in fact, through a puzzle thrust reverser word process:

For example, if we have a puzzle that is gabc (assuming the current puzzle length is only 4), then it is possible

word What?

https://translate.googleusercontent.com/translate_f 30/37
12/8/21, 12:27 PM Untitled
1. First, condition one must be met, that is, word must contain the first letter g ;
2. Then there is condition two, every word in the word has appeared in the puzzle , so the possible words include

g , ga , gb , gc , gab , gac , gbc , gabc .

If you use 1 and 0 to represent the choice of each puzzle , it actually corresponds to 1000, 1100, 1010, 1001,
1110, 1101, 1011, 1111.

After understanding this process, we need to perform word frequency statistics on words , we can use the "hash table" to record the same
The meaning of the word appeared many times (the same meaning as the meaning of the letter containing the same type of word , because the answer and
The repeated characters of word are irrelevant)

What is the complexity/calculation of this?

1. Count the word frequency of all words. The calculated amount * 10


is 50 of
, The order magnitude
5 is 10 6
2. Corresponding to each puzzle , since its length is determined to be 7, so all enumerate all possible "mystery"

6 can be seen as O (1) , checking every possible "answer" in the words out
Quantity is not =2 64,
The number of times is passed through the hash table, which is also approximately O (1) . Therefore, when determining the answer to a puzz

, Theamount
The length of words is irrelevant. The calculated 10 4
order ofismagnitude is 10 4

The amount of calculation per second of the


Around computer
(OJ 10 7 10 6
tester isisusually ~ 10 7 Between), so you can live.

Code:

Page 42

class Solution {
public List < Integer > findNumOfValidWords ( String [] ws, String [] ps) {
// Use the "hash table" to count the binary values ​corresponding to all words
Map < Integer , Integer > map = new HashMap <>();
for ( String w : ws) {
int t = getBin (w);
map. put (t, map. getOrDefault (t, 0 ) + 1 );
}
// Determine how many answers each puzzle has
List < Integer > ans = new ArrayList <>();
for ( String p : ps) ans. add ( getCnt (map, p));
return ans;
}
int getCnt ( Map < Integer , Integer > map, String str) {
int ans = 0 ;
int m = str. length ();
char [] cs = str. toCharArray ();
// The position of the first character of the current puzzle in the binary value
int first = cs[ 0 ] - 'a' ;
// Enumerate all subsets of "Keep the first letter"
// That is, we need to fix the first letter of the puzzle first, and then enumerate whether the remaining 6 bits are reserved
// Since it is binary, each bit has two choices of 0 and 1, so there are 2^6 possibilities, that is, 2^6 = 1 << (7-1) = 64
// i represents the binary representation of the ``last six digits'' of the subset of all ``reserve the first letter''
for ( int i = 0 ; i < ( 1 << (m - 1 )); i ++ ) {
// u represents the current possible answer. First extract the first letter
int u = 1 << first;
// Enumerate every digit after the "first letter"
for ( int j = 1 ; j < m; j ++ ) {
// If the current position is 1, it means that the position should be kept, and the letter at that position is appended to the answer u
if (((i >> (j - 1 )) & 1 ) != 0 ) u += 1 << (cs[j] - 'a' );
}
// Query whether such characters appear in `words` and how many times do they appear
if (map. containsKey (u)) ans += map. get (u);
}
return ans;
}
// The letters contained in str are identified by binary
// If str = abz, the corresponding binary is 100...011 (26 bits in total, a-z from right to left)

https://translate.googleusercontent.com/translate_f 31/37
12/8/21, 12:27 PM Untitled
int getBin ( String str) {
int t = 0 ;
char [] cs = str. toCharArray ();
for ( char c : cs) {
// Which one of the binary digits corresponds to each character
int u = c - 'a' ;
// If the current position is 0, it means that it has not been recorded yet, then record (not repeat record)
if ((t >> u & 1 ) == 0 ) t += 1 << u;

Page 43

}
return t;
}
}

• Time complexity: O ( words . Length ∗ words [ i ]. length + puzzles . Length )


• Space complexity: word and puzzle have maximum length and fixed length respectively, and the space used depends mainly on

Measure the length of the array. The complexity is O ( words . Length + puzzles . Length )

Bit operation description


a >> b & 1 means to check whether the b-th bit of a is 1, there are two possibilities: 0 or 1

a += 1 << b means to set the b-th bit of a to 1 (applicable when the b-th bit is 0)

If you don’t want to write the pre-judgment that the b-th bit is 0, a += 1 << b can also be changed to a |= 1 << b

PS. 1 binary is the least significant bit is 1 , the other bits to 0 oh

The above two operations occur very frequently in bit operations. It is recommended that every student deepen their understanding.

Reviews
After the solution of this problem was posted to LeetCode, many students still didn't understand it or did not understand it.

So I rethinked every aspect of this question.

This question is Hard, because it examines things that are against the "intuition" of human nature:

1. State compression: which letters appear in a word cannot be recorded by our intuitive map/set
Record, and use a binary number with a length of 26 to record. For a letter, it needs to be calculated in the binary
Which digit in the number, if it has appeared, it is represented by 1, and if it has not appeared, it is represented by 0
2. Positive difficult the anti-: not from the words starting array, to check what word to meet the requirements; and to turn
From the puzzle starting to enumerate the current puzzle all legal Word , go to determine the legality of these
How many times does word appear in the real words array

Page 44

Everyone should try to understand the rationality of this kind of thinking. When this kind of thinking also forms consciousness, this kind of question is not
https://translate.googleusercontent.com/translate_f 32/37
12/8/21, 12:27 PM Untitled

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Title description
This is the 1711. Big meal count on LeetCode , and the difficulty is medium .

Tag: "Hash Table", "Bit Operation"

A big meal refers to a meal that contains exactly two different meals, and the sum of its deliciousness is equal to a power of two.

You can make a big meal with any two dishes.

Give you an integer array deliciousness, where deliciousness[i] is the deliciousness of the i-th meal, return you can
+ 7needs
The number of different meals made with the meals in the array. The result Take to
theberemainder.
10 9

Note that as long as the subscripts of the meals are different, they can be regarded as different meals, even if they are the same degree of deliciousness.

Example 1:

Input: deliciousness = [1,3,5,7,9]

Output: 4

Explanation: The combination of deliciousness of the meal is (1,3), (1,7), (3,5) and (7,9).
The sum of their respective delicacy levels are 4, 8, 8, and 16, which are all powers of 2.

Example 2:

Input: deliciousness = [1,1,1,3,3,3,7]

Output: 15

Explanation: The combination of deliciousness of the meal is 3 kinds (1,1), 9 kinds (1,3), and 3 kinds (1,7).

hint:

• 1 <= deliciousness.length <= 10 5

Page 45

• 0 <= deliciousness[i] <= 2 20

Enumerate the previous number ( TLE )


A simple idea is to traverse all the numbers in deliciousness from front to back , and when traversing to the subscript i , turn back
Check the index below i whether the number capable of deliciousness [ i ] added to form two powers.

This approach is O ( n 2 ) To prevent the same value from being calculated repeatedly, we can use the "hash table" to record a certain number
2 ) . the algorithm is still O ( n
How many times have been found, but this does not change

And we need a check method to determine whether a certain number is a power of 2 :

• The naive approach is to apply trial division to x . Of course, due to accuracy issues, we need to use multiplication to achieve trial division;

https://translate.googleusercontent.com/translate_f 33/37
12/8/21, 12:27 PM Untitled
• Another better way is to use bitwise operations to find the nearest power of 2 that conforms to "greater than or equal to x " , and then
Then judge whether it is the same as x .

How big is the gap between the two practices? The complexity of method one is O (log n ) and the complexity of method two is O (1) .

According to the data range 0 <= deliciousness [ i ] <= 2, Method


20 one is to execute no more than 22 cycles at most.

Obviously, which method of judging the power of 2 is not the key, and it is only stuck at 60/70 and 62/70 in the OJ judgment.
On the TLE.

But through this analysis, we


I can find that the method
The of "enumerating
practice the previous
of the former number"number" is the
is related to nsame as the enumeration "may appear
, while
The power of 2 " has a clear range, which leads to our second solution.

Code:

Page 46

class Solution {
int mod = ( int ) 1e9 + 7 ;
public int countPairs ( int [] ds) {
int n = ds.length;
long ans = 0 ;
Map < Integer , Integer > map = new HashMap <>();
for ( int i = 0 ; i < n; i ++ ) {
int x = ds[i];
for ( int other : map. keySet ()) {
if ( check (other + x)) ans += map. get (other);
}
map. put (x, map. getOrDefault (x, 0 ) + 1 );
}
return ( int )(ans % mod);
}
boolean check ( long x) {
// method one
// long cur = 1;
// while (cur <x) {
// cur = cur * 2;
//}
// return cur == x;

// Method Two
return getVal (x) == x;
}
long getVal ( long x) {
long n = x - 1 ;
n |= n >>> 1 ;
n |= n >>> 2 ;
n |= n >>> 4 ;
n |= n >>> 8 ;
n |= n >>> 16 ;
return n < 0 ? 1 : n + 1 ;
}
}

https://translate.googleusercontent.com/translate_f 34/37
12/8/21, 12:27 PM Untitled

• Time complexity: O ( n2 )
• Space complexity: O ( n )

Page 47

Enumeration 2 of powers (inclusion and exclusion)


According to the analysis of the naive solution, we can first use the "hash table" to calculate all the numbers that have appeared in deliciousness
statistics.

Then for each number x , check all possible powers of 2 i , and then check from the "hash table" whether t = i − x exists
Now, and realize counting.

Some details: If t = i − x exists in the hash table , and t = x , then the number of solutions should be ( cnts [ x ] −
1) ∗ cnts [ x ] ; the other general cases are cnts [ t ] ∗ cnts [ x ] .

At the same time, in this way of counting, we will count two tuples ( x , t ) separately (traversing x and traversing t ), so the most
Later, the principle of tolerance and exclusion is used to halve the repeated count.

Code:

class Solution {
int mod = ( int ) 1e9 + 7 ;
int max = 1 << 22 ;
public int countPairs ( int [] ds) {
Map < Integer , Integer > map = new HashMap <>();
for ( int d : ds) map. put (d, map. getOrDefault (d, 0 ) + 1 );
long ans = 0 ;
for ( int x : map. keySet ()) {
for ( int i = 1 ; i < max; i <<= 1 ) {
int t = i - x;
if (map. containsKey (t)) {
IF (T == X) ANS + = (Map. GET (X) - . 1 ) * 1L * Map. GET (X);
else ans += map. get (x) * 1L * map. get (t);
}
}
}
ans >>= 1 ;
return ( int )(ans % mod);
}
}

• Time complexity: According to the data range, let C .be 2 21


The complexity is O ( n ∗ log C )
• Space complexity: O ( n )

Page 48

https://translate.googleusercontent.com/translate_f 35/37
12/8/21, 12:27 PM Untitled

Enumeration 2 powers (side edge traversal statistics)


Of course, we can also adopt the method of "traversing and counting at the same time", so that the remainder operation can be placed in the traversal logic
To do this, by the way, it is realized that long is not used for counting (and the remainder is not used for % ).

Code:

class Solution {
int mod = ( int ) 1e9 + 7 ;
int max = 1 << 22 ;
public int countPairs ( int [] ds) {
Map < Integer , Integer > map = new HashMap <>();
int ans = 0 ;
for ( int x : ds) {
for ( int i = 1 ; i < max; i <<= 1 ) {
int t = i - x;
if (map. containsKey (t)) {
ans += map. get (t);
if (ans >= mod) ans -= mod;
}
}
map. put (x, map. getOrDefault (x, 0 ) + 1 );
}
return ans;
}
}

• Time complexity: According to the data range, let C .be 2 21


The complexity is O ( n ∗ log C )
• Space complexity: O ( n )

** More exciting content, welcome to pay attention:No. public / Github / LeetCode / know almost **

Update Tips : The update time of this topic is 2021-10-07 , and it will be updated once every 2-4 weeks.

Download the latest thematic collection data, you can follow the public account
", return
"Miyamizu
to Taiwan
Mitsuba’s
to replyDiary
"Bitwise
of Writing
Operation"
Questions
for download
", return to Taiwan and re
Link.

If you think the topic is good, you can ask the author for candy:

Page 49

https://translate.googleusercontent.com/translate_f 36/37
12/8/21, 12:27 PM Untitled

Copyright statement: Please keep the source Wiki for any form of reprint.

https://translate.googleusercontent.com/translate_f 37/37

You might also like