【LeetCode】位运算 bit manipulation(共32题)

【78】Subsets html

给了一个 distinct 的数组,返回它全部的子集。算法

Example:
Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

 题解:我是直接dfs(backtracking)了,有个小地方写错了(dfs那里),至少调整了十多分钟,下次不要写错了。数组

 1 class Solution {
 2 public:
 3     vector<vector<int>> subsets(vector<int>& nums) {
 4         n = nums.size();
 5         vector<int> visit(n, 0);
 6         vector<int> temp;
 7         if (n == 0) { return ans; }
 8         dfs(nums, visit, temp, 0);
 9         return ans;
10     }
11     void dfs(const vector<int>& nums, vector<int>& visit, vector<int>& temp, int cur_idx) {
12         ans.push_back(temp);
13         if (cur_idx == n) { return; }
14         for (int i = cur_idx; i < n; ++i) {
15             if (!visit[i]) {
16                 visit[i] = 1;
17                 temp.push_back(nums[i]);
18                 dfs(nums, visit, temp, i + 1); //一开始写成了 dfs(nums, visit, temp, cur_idx + 1) 挂了半天
19                 visit[i] = 0;
20                 temp.pop_back();
21             }
22         }
23         return;
24     }
25     vector<vector<int>> ans;
26     int n;
27 };
backtracking

我看分类是 位运算,学习一下位运算解法。https://leetcode.com/problems/subsets/discuss/27288/My-solution-using-bit-manipulationide

题解的解释参考:https://www.mathsisfun.com/sets/power-set.html (有点像状态压缩的感受)学习

 

 1 //bit manipulation, 我认为是状态压缩的最简单的题.
 2 class Solution {
 3 public:
 4     vector<vector<int>> subsets(vector<int>& nums) {
 5         const int n = nums.size();
 6         if (n == 0) { return vector<vector<int>>{}; }
 7         // n 个元素一共有 2^n 个子集。
 8         int tot = pow(2, n);
 9         vector<vector<int>> ans(tot, vector<int>{});
10         // 而后用二进制一个一个往里面塞
11         for (int i = 0; i < n; ++i) {
12             for (int j = 0; j < tot; ++j) {
13                 if (j >> i & 1) {
14                     ans[j].push_back(nums[i]);
15                 }
16             }
17         }
18         return ans;
19     }
20 
21 };
bit manipulation

 

【136】Single Number (2018年11月4日)(剑指offer上有个变种题,有两个数只出现了一次,求出出现一次的这两个数)ui

给了一个数组,说数组里面除了一个数只出现了一次,其余数都出现了两次。找出只出现一次的那个数。编码

题解:出现两次的数取异或以后为0,把所有数字异或起来,最后结果就是要求的那个数。spa

 1 class Solution {
 2 public:
 3     int singleNumber(vector<int>& nums) {
 4         int ans = 0;
 5         for (int i = 0; i < nums.size(); ++i) {
 6             ans ^= nums[i];
 7         }
 8         return ans;
 9     }
10 };
View Code

  

【137】Single Number II 3d

【169】Majority Element code

【187】Repeated DNA Sequences 

【190】Reverse Bits 

 

【191】Number of 1 Bits (2018年11月4日,无聊作的)

给了一个数的 hamming weight,返回它的二进制中  1 的个数。

题解:方法同 231, n & (n-1) 这个表达式能消除 n 的二进制表达中最右边的一个 1. 

 1 class Solution {
 2 public:
 3     int hammingWeight(uint32_t n) {
 4         int cnt = 0;
 5         while (n) {
 6             cnt++;
 7             n = n & (n-1);
 8         }
 9         return cnt;
10     }
11 };
View Code

 

【201】Bitwise AND of Numbers Range 

 

【231】Power of Two (相关题目 342 Power of Four)(2018年11月4日,无聊作的)

给了一个数,判断它是否是2的幂。

题解:2的幂的二进制中只有一个1,因此咱们用 num&(num-1) == 0 判断是否是2的幂次。 

1 class Solution {
2 public:
3     bool isPowerOfTwo(int n) {
4         return n > 0 && (n & (n-1)) == 0;
5     }
6 };
View Code

另外,还有判断一个数是否是3的幂的(326),一个数是否是4的幂的(342)。 

 

【260】Single Number III  (2018年11月24日,算法群) 

题解:本题剑指offer书上好像是有的。

 

【268】Missing Number 

 

【318】Maximum Product of Word Lengths (2019年3月26日)

给了一组wordlist,返回里面两个单词的长度的乘积最大是多少。要求这两个单词里面不能有重复的字母。题目中给定全部单词都是小写字母。

题解:由于已经说明了每一个单词的字母都是小写字母,因此咱们能够用一个32位整数来编码当前单词是否出现过这个字母。重要代码以下:

 

x = words[i][j] - 'a'
code |= (1 << x) 

 

 而后判断两个单词是否有相同字母,使用以下语句判断: code[i] & code[j] == 0

 1 class Solution {
 2 public:
 3     int maxProduct(vector<string>& words) {
 4         const int n = words.size();
 5         vector<int> codes(n, 0);
 6         for (int i = 0; i < n; ++i) {
 7             for (int j = 0; j < words[i].size(); ++j) {
 8                 int x = words[i][j] - 'a';
 9                 codes[i] |= (1 << x);
10             }
11         }
12         int res(0);
13         for (int i = 0; i < n; ++i) {
14             for (int j = i + 1; j < n; ++j) {
15                 if (codes[i] & codes[j]) {continue;}
16                 int length = (int)words[i].size() * words[j].size();
17                 res = max(res, length);
18             }
19         }
20         return res;
21     }
22 };
View Code

 

【320】Generalized Abbreviation 

 

【338】Counting Bits 

 

【342】Power of Four (231题的升级版,判断是否是4的幂)(2018年11月4日,无聊作的)

给了一个数,判断这个数是否是4的幂。

题解:多是负数,因此先把负数排除。一个数是4的幂的前提条件是它的2的幂,2的幂的二进制中只有一个1,因此用 num&(num-1) == 0 判断是否是 2 的幂。(这个方法也用在数一个数的二进制中有几个1用到了,【191】题,Number of 1 Bits)。而后增长判断它是否是 4 的幂,就是若是一个数是 2 的幂,那么增长一个条件, num % 3 == 1,知足这个条件,它就是 4 的幂。

1 //一个数是4的幂次,首先它要是2的幂次,2的幂次怎么求,2的幂次二进制中只有一个1.
2 class Solution {
3 public:
4     bool isPowerOfFour(int num) {
5         return num > 0 && (num&(num-1))==0 && num % 3 == 1;
6     }
7 };
View Code

 discuss中还有 & 一堆5的,那个要研究一下。

 

【371】Sum of Two Integers  (2018年11月26日)

返回 a + b 的答案,不能用 +。

题解:位运算。为啥我也还没搞懂。先写着。

https://leetcode.com/problems/sum-of-two-integers/discuss/84278/A-summary:-how-to-use-bit-manipulation-to-solve-problems-easily-and-efficiently

 1 class Solution {
 2 public:
 3     int getSum(int a, int b) {
 4         do {
 5             int sum = a ^ b;
 6             int carry = (a & b) << 1;
 7             a = sum, b = carry;
 8         } while (b != 0);
 9         return a;
10     }
11 };
View Code

 

【389】Find the Difference 

【393】UTF-8 Validation 

【397】Integer Replacement 

【401】Binary Watch 

【405】Convert a Number to Hexadecimal 

【411】Minimum Unique Word Abbreviation 

【421】Maximum XOR of Two Numbers in an Array 

 

【461】Hamming Distance (2019年2月16日)

两个整数对应二进制位置不一样的个数叫作hamming distance。给了两个正整数 x 和 y,计算他们的hamming distance。

题解:我这里想强调下左移右移。左移低位补0,至关于乘以2,右移,若是是正数的话,高位补0,若是是负数的话,低位补0.

 1 class Solution {
 2 public:
 3     int hammingDistance(int x, int y) {
 4         int res = 0;
 5         while (x || y) {
 6             res += (x & 1) ^ (y & 1);
 7             x >>= 1; y >>= 1;
 8         }
 9         return res;
10     }
11 };
View Code

 

【476】Number Complement (2019年2月16日)

返回一个正整数的补码。

The complement strategy is to flip the bits of its binary representation.

题解:咱们用一个unsigned mask,mask一开始是 ~0 = FFFFFFFF,而后咱们把 mask 尾部跟 number 有重叠的部分全 set 成 0。而后 返回 ~num & ~mask

1 class Solution {
2 public:
3     int findComplement(int num) {
4         unsigned mask = ~0;
5         while (num & mask) {mask <<= 1;}
6         return ~num & ~mask;
7     }
8 };
View Code

 

【477】Total Hamming Distance 

【693】Binary Number with Alternating Bits 

【751】IP to CIDR 

【756】Pyramid Transition Matrix 

【762】Prime Number of Set Bits in Binary Representation 

【784】Letter Case Permutation 

【898】Bitwise ORs of Subarrays

相关文章
相关标签/搜索