leetcode of algorithm interview in Dachang 9. Bit operation
Video tutorial (efficient learning): Click to learn
catalog:
6. Depth first & breadth first
10. Recursion & divide and conquer
Bit operation basis:
All digital computers in the program are stored in binary in memory. Bit operation is to directly operate the binary of integers in memory. Because it is operated directly in memory, it does not need to be converted to decimal, so the processing speed is very fast
Common bit operation
x & 1 === 0 //Judge parity x & (x - 1) //Clear rightmost 1 x & -x //Get the rightmost 1
191. Number of bit 1 (easy)
Method 1: loop each binary bit
- Idea: directly loop each bit in the binary, judge whether it is 1, and count the number of 1
- Complexity analysis: time complexity O(k), k=32. Space complexity is O(1)
Js:
var hammingWeight = function(n) { let ret = 0; for (let i = 0; i < 32; i++) { if ((n & (1 << i)) !== 0) {//Let 1 constantly move left to judge whether the bit is 1 ret++; } } return ret; };
Java:
public class Solution { public int hammingWeight(int n) { int ret = 0; for (int i = 0; i < 32; i++) { if ((n & (1 << i)) != 0) { ret++; } } return ret; } }
Method 2: optimize the process of the cycle
- Idea: skillfully use binary formula X & (x-1) to express, remove the rightmost 1 in binary, and accelerate the cycle process
- Complexity analysis: the time complexity is O(k), K is the number of 1 in binary, and in the worst case, all bits are 1. The spatial complexity is O(1)
js:
var hammingWeight = function(n) { let ret = 0; while (n) { n &= n - 1;//Keep erasing the rightmost 1 ret++; } return ret; };
java:
public class Solution { public int hammingWeight(int n) { int ret = 0; while (n != 0) { n &= n - 1; ret++; } return ret; } }
231. Power of 2(easy)
Method 1. Binary
- Idea: a number is a power of 2. There is only one 1 in the binary of this number, that is, the number > 0. At the same time, after eliminating the only 1, it is 0
- Complexity: time complexity O(1). Space complexity O(1)
Js:
var isPowerOfTwo = function(n) { return n > 0 && (n & (n - 1)) === 0; };
Java:
class Solution { public boolean isPowerOfTwo(int n) { return n > 0 && (n & (n - 1)) == 0; } }
Method 2. Whether it is the divisor of the power of maximum 2
- Idea: the maximum power of 2 is 2 ^ 30 = 1073741824. Judge whether n is the divisor of 2 ^ 30.
- Complexity: time complexity O(1). Space complexity O(1)
js:
var isPowerOfTwo = function(n) { const MAX = 1 << 30; return n > 0 && MAX % n === 0; };
Java:
class Solution { static final int MAX = 1 << 30; public boolean isPowerOfTwo(int n) { return n > 0 && MAX % n == 0; } }
338. Bit count (easy)
Method 1. Cycle
- Idea: loop 0-n to calculate the number of 1 in each binary.
- Complexity: time complexity O(nk), K is the complexity of an integer statistical binary 1. In the worst case, k=32. The spatial complexity is O(1)
js:
var countBits = function(n) { const bits = new Array(n + 1).fill(0); for (let i = 0; i <= n; i++) { bits[i] = countOnes(i); } return bits }; const countOnes = (x) => { let ones = 0; while (x > 0) { x &= (x - 1); ones++; } return ones; }
Java:
class Solution { public int[] countBits(int n) { int[] bits = new int[n + 1]; for (int i = 0; i <= n; i++) { bits[i] = countOnes(i); } return bits; } public int countOnes(int x) { int ones = 0; while (x > 0) { x &= (x - 1); ones++; } return ones; } }
Method 2. Dynamic programming
- Idea: bits[i] represents the number of 1 in the binary of I, then bits[i-1] is the value after bits[i] removes a 1, and I & (I - 1) is the lowest 1
Therefore, the state transition equation is bits [i] = bits [I & (I - 1)] + 1, and the number of 1 in each binary from 1-n can be calculated repeatedly
- Complexity: time complexity O(n). The spatial complexity is O(1)
Js:
var countBits = function(n) { const bits = new Array(n + 1).fill(0); for (let i = 1; i <= n; i++) { bits[i] = bits[i & (i - 1)] + 1; } return bits; };
Java:
class Solution { public int[] countBits(int n) { int[] bits = new int[n + 1]; for (int i = 1; i <= n; i++) { bits[i] = bits[i & (i - 1)] + 1; } return bits; } }
389. Find a different( easy)
Method 1. Counting
- Idea: the circular string s counts the number of each character. Every time the circular string t appears, the number of characters in s will be reduced by 1. If the number of characters is reduced to less than 0, this character is the answer
- Complexity: time complexity O(n), n is the length of the string. Spatial complexity O(k), K is the size of the character set
js:
var findTheDifference = function(s, t) { const cnt = new Array(26).fill(0); for (const ch of s) {//Loop string s counts the number of characters per character cnt[ch.charCodeAt() - 'a'.charCodeAt()]++; } for (const ch of t) {//Each time the character in s appears in the circular string t, the number of corresponding characters is reduced by 1 cnt[ch.charCodeAt() - 'a'.charCodeAt()]--; if (cnt[ch.charCodeAt() - 'a'.charCodeAt()] < 0) {//If the character is reduced to less than 0, this character is the answer return ch; } } return ' '; };
java:
class Solution { public char findTheDifference(String s, String t) { int[] cnt = new int[26]; for (int i = 0; i < s.length(); ++i) { char ch = s.charAt(i); cnt[ch - 'a']++; } for (int i = 0; i < t.length(); ++i) { char ch = t.charAt(i); cnt[ch - 'a']--; if (cnt[ch - 'a'] < 0) { return ch; } } return ' '; } }
Method 2. Summation
- Idea: count the sum of Unicode characters in strings s and t. The difference between the two sums is different characters
- Complexity: time complexity O(n). Space complexity O(1)
js:
var findTheDifference = function(s, t) { let as = 0, at = 0; for (let i = 0; i < s.length; i++) {//Counts the sum of Unicode values of characters in string s as += s[i].charCodeAt(); } for (let i = 0; i < t.length; i++) {//Counts the sum of Unicode values of characters in string t at += t[i].charCodeAt(); } return String.fromCharCode(at - as);//The difference between two sums is a different character };
java:
class Solution { public char findTheDifference(String s, String t) { int as = 0, at = 0; for (int i = 0; i < s.length(); ++i) { as += s.charAt(i); } for (int i = 0; i < t.length(); ++i) { at += t.charAt(i); } return (char) (at - as); } }
3. Square bit operation
- Idea: loops s and t keep XOR. The same element XOR is equal to 0, so the only different characters will be left in the end
- Complexity: time complexity O(n). Space complexity O(1)
js:
//s = "abcd", t = "abcde" var findTheDifference = function(s, t) { let ret = 0;//Loops s and t are constantly XOR. The same element XOR is equal to 0, so the only different characters will be left in the end for (const ch of s) { ret ^= ch.charCodeAt(); } for (const ch of t) { ret ^= ch.charCodeAt(); } return String.fromCharCode(ret); };
java:
class Solution { public char findTheDifference(String s, String t) { int ret = 0; for (int i = 0; i < s.length(); ++i) { ret ^= s.charAt(i); } for (int i = 0; i < t.length(); ++i) { ret ^= t.charAt(i); } return (char) ret; } }
268. Missing numbers (easy)
Method 1. Sorting: in the circular array, see if the latter number is 1 larger than the previous one
Method 2. Hash table: insert the elements in the array into the hash table, and then cycle whether the numbers in 0 ~ num.length-1 are all in the hash table
Method 3. Sum: 0 ~ num.length-1 sum minus the sum in num
Method 4: bit operation
- Idea: the same number XOR is 0
- Complexity: time complexity O(n), space complexity O(1)
js:
//nums = [3,0,1] //index = 0,1,2 var missingNumber = function (nums) { let missing = nums.length for (let i = 0; i < nums.length; i++) {//The same number XOR is 0 missing = missing ^ nums[i] ^ (i) } return missing }
java
class Solution { public int missingNumber(int[] nums) { int missing = nums.length; for (int i = 0; i < nums.length; i++) { missing ^= i ^ nums[i]; } return missing; } }