Leetcode ブラッシングノート (C++) - ビット操作

Leetcode ブラッシングノート (C++) - ビット操作

質問をブラッシュアップする過程でアイデアを整理し、ここにまとめて共有します。
github アドレス: https://github.com/lvjian0706/Leetcode-solutions
github プロジェクトは新しく作成されたばかりで、C++ と Python をベースに整理されたコードやアイデアが次々とアップロードされます。同時に、基本的な並べ替えアルゴリズムも並べ替えてアップロードされます。

136. 一度だけ現れる数字

空ではない整数の配列を指定すると、1 回しか出現しない特定の要素を除いて、各要素は 2 回出現します。1 回だけ出現する要素を見つけます。

説明:
アルゴリズムには線形時間計算量が必要です。余分なスペースを使わずに実行できますか?

例 1:
入力: [2,2,1]
出力: 1
例 2:
入力: [4,1,2,1,2]
出力: 4

class Solution {
    
    
public:
    /*
    由于时间和空间限制,所以使用二进制的异或运算解答即可;
    */
    int singleNumber(vector<int>& nums) {
    
    
        int ans = nums[0];
        for(int i=1; i<nums.size(); i++){
    
    
            ans ^= nums[i];
        }
        return ans;
    }
};

191. ビット1の数

符号なし整数を入力として受け取り、そのバイナリ表現で「1」の桁の数 (ハミング重みとも呼ばれます) を返す関数を作成します。

例 1:
入力: 00000000000000000000000000001011
出力: 3
説明: 入力バイナリ文字列 00000000000000000000000000001011 では、合計 3 ビットが「1」です。
例 2:
入力: 00000000000000000000000010000000
出力: 1
説明: 入力バイナリ文字列 00000000000000000000000010000000 では、合計 1 ビットが「1」になります。
例 3:
入力: 11111111111111111111111111101
出力: 31
説明: 入力バイナリ文字列 11111111111111111111111111101 では、合計 31 ビットが「1」です。

方法1class Solution {
    
    
public:
    /*
    返回二进制表达式中数字位数为 ‘1’ 的个数:
    求二进制数(对2取余后整除2),当该位为1时,ans++;
    */
    int hammingWeight(uint32_t n) {
    
    
        int ans = 0;
        while(n!=0){
    
    
            ans += (n % 2);
            n /= 2;
        }
        return ans;
    }
};

方法2class Solution {
    
    
public:
    /*
    返回二进制表达式中数字位数为 ‘1’ 的个数:
    n = n & (n-1) : 将最后一个1置0;
    将最后一个1循环置0,直到所有位上都是0;
    */
    int hammingWeight(uint32_t n) {
    
    
        int ans = 0;
        while(n){
    
    
            n = n & (n-1);
            ans++;
        }
        return ans;
    }
};

260. 一度だけ現れる数字Ⅲ

整数配列 nums を指定すると、ちょうど 2 つの要素は 1 回だけ現れ、他のすべての要素は 2 回現れます。1 回だけ出現する 2 つの要素を見つけます。

例:
入力: [1,2,1,3,2,5]
出力: [3,5]

class Solution {
    
    
public:
    /*
    找出只出现一次的那两个元素:因为是常数空间,考虑位运算:
    x & (-x) :保留位中最右边1,且将其余的1设为0。 
    1. xy ^= nums[i]:先找到只出现过一次的两个数的异或结果;
    2. dif = xy & (-xy):找出x与y不同的一位(最右边一位);
    3. x ^= nums[i]:找到x;
    4. xy^x:找到y;
    */
    vector<int> singleNumber(vector<int>& nums) {
    
    
        vector<int> ans;
        int xy=0;
        for(int i=0; i<nums.size(); i++){
    
    
            xy ^= nums[i];
        }
        int dif = xy & (-xy);
        int x = 0;
        for(int i=0; i<nums.size(); i++){
    
    
            if(nums[i]&dif){
    
    
                x ^= nums[i];
            }
        }
        ans.push_back(x);
        ans.push_back(xy^x);
        return ans;
    }
};

338. ビットを数える

負ではない整数が与えられます。0 ≤ i ≤ num の範囲内の各数値 i について、その 2 進数の 1 の数を数え、それらを配列として返します。

例 1:
入力: 2
出力: [0,1,1]
例 2:
入力: 5
出力: [0,1,1,2,1,2]

class Solution {
    
    
public:
    /*
    对于0≤i≤num范围中的每个数字i,计算其二进制数中的1的数目并将它们作为数组返回:动态规划问题
    1. 奇数:二进制表示中,奇数一定比前面那个偶数多一个 1,因为多的就是最低位的 1。
    2. 偶数:二进制表示中,偶数中 1 的个数一定和除以 2 之后的那个数一样多。因为最低位是 0,除以 2 就是右移一位,也就是把那个 0 抹掉而已,所以 1 的个数是不变的。
    */
    vector<int> countBits(int num) {
    
    
        vector<int> dp(num+1);
        dp[0] = 0;
        for(int i=1; i<num+1; i++){
    
    
            if(i%2==0){
    
    
                dp[i] = dp[i/2];
            }
            else{
    
    
                dp[i] = dp[i-1] + 1;
            }
        }
        return dp;
    }
};

おすすめ

転載: blog.csdn.net/weixin_43273742/article/details/107740748