Introduction
Video: https://www.youtube.com/watch?v=NLKQEOgBAnw&t=189s
Two’s Complement
Notes: https://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html
8-bit integer, Use first slot to represent the sign of the number. 0
=> +
, 1
=> -
1 | 18 : 00010010 + ? = 00000000 |
Shifting
Logical & Arithmatic
1 | 00010111 => 23 |
Masks
1 | 0 & 0 = 0 |
Parity Check
Parity checks are used to detect single bit errors in data storage and communication. The parity of a binary value is 1 if the number of 1s in the value is odd; otherwise it’s 0.
General Tricks1
2
3
4
5
6
7
8
9
10
111. x & (x - 1) => x with its lowest set bit erased
x: 00101100
x - 1: 00101011
x&(x-1):00101000
2. x & ~(x - 1) => extracts the lowest set bit of x
x: 00101100
~(x - 1):11010100
x&~(x-1):00000100
3. Cache results in an array-based lookup table
191. Number of 1 Bits
Leetcode: https://leetcode.com/problems/number-of-1-bits/
[Solution]
Use a mask from 000...01
to 1000...0
to test if any of the slots is 1
1 | def hammingWeight(self, n): |
231. Power of Two
Leetcode: https://leetcode.com/problems/power-of-two/
1 | def isPowerOfTwo(self, n): |
190. Reverse Bits
1 | def reverseBits(self, n): |
Find a closest integer with the same weight
Define the weight of a nonnegative integer x to be the number of bits that are set to 1.
[Solution]
Suppose we flip the bit at index k1 and flip the bit at index k2, k1 > k2. Then the absolute value of the difference between the original integer and the new one is 2^k1 - 2^k2. Since we must preserve the weight, we should make k1 as small as possible and k2 as close to k1.
In summary, the correct approach is to swap the two rightmost consecutive bits that differ.
43. Multiply Strings
Leetcode: https://leetcode.com/problems/multiply-strings/
[Solution] Iterate through x, adding 2^k*y to the result if the kth bit of x is 1. 2^k*y can be computed by left-shifting y by k.
1 | def multiply(self, num1: str, num2: str) -> str: |
29. Divide Two Integers
[Solution]
- Starting from k = 32, if 2^k y < x: x = x - 2^k y, res += 2^k
- O(N^2)
1 | def divide(self, x: 'int', y: 'int') -> 'int': |
50. Pow(x, n)
Leetcode: https://leetcode.com/problems/powx-n/
1 | def myPow(self, x: float, n: int) -> float: |
393. UTF-8 Validation
Leetcode: https://leetcode.com/problems/utf-8-validation/
1 | def validUtf8(self, data: 'List[int]') -> 'bool': |
136. Single Number
Leetcode: https://leetcode.com/problems/single-number/
[Solution]
0 ^ any = any
any ^ any = 0
1 | def singleNumber(self, nums: List[int]) -> int: |
67. Add Binary
Leetcode: https://leetcode.com/problems/add-binary/
Solution: The key is the carry
.
1 | def addBinary(self, A, B): |
1073. Adding Two Negabinary Numbers
Leetcode: https://leetcode.com/problems/adding-two-negabinary-numbers/
Solution:
The carry
can have three status: -1
, 0
, and 1
.
1 | def addNegabinary(self, arr1: List[int], arr2: List[int]) -> List[int]: |
1017. Convert to Base -2
Leetcode: https://leetcode.com/problems/convert-to-base-2/
Solution: Convert to base 2 first, and then add -
https://en.wikipedia.org/wiki/Negative_base#Addition
1 | def base2(self, N): |
393. UTF-8 Validation
Leetcode: https://leetcode.com/problems/utf-8-validation/
1 | def validUtf8(self, data): |