【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

相關文章
相關標籤/搜索