[leetcode] 位操作题解

【本文持续更新】

78. 子集

题目: 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
示例:

输入: nums = [1,2,3]
输出:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

本题做过好几遍了, 之前用的是回溯法, 本次使用的是位操作的思想。

位操作解法: 将 \(nums\) 的每一个位置看作一个 \(bit\),如果某个 \(bit\) 为1,表示 \(nums[i]\) 需要加入子集,否则不加入。显然, 每个子集都对应一个比特串, 比特串从 \(0...0\)\(1...1\) 变化(也就从另外一个角度证明了子集的数目为 \(2^n\) )。

下面举例说明, 当 $ nums = [1,2] $ 时:

比特位 对应子集
0 0 [ ]
0 1 [2]
1 0 [1]
1 1 [1,2]

位操作代码(C++):

class Solution
{
public:
    vector<vector<int>> subsets(vector<int> &nums)
    {
        vector<vector<int>> vv;
        int total = 1 << nums.size();
        for (int i = 0; i < total; i++)
        {
            vv.push_back(getItem(i, nums));
        }

        return vv;
    }

    vector<int> getItem(int n, const vector<int> &nums)
    {
        vector<int> v;
        for (int i = 0; i < nums.size(); i++)
        {
            if ((n >> i) & 0x1)
                v.push_back(nums[i]);
        }
        return v;
    }
};

回溯法代码(python):

class Solution:
    def __init__(self):
        self.ans = list()
        self.ans.append([])

    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        cur = []
        self.helper(cur, nums)
        return self.ans

    def helper(self, cur: list, nums: list):
        for i in range(0, len(nums)):
            cur.append(nums[i])
            self.ans.append(list(cur))
            self.helper(cur, nums[(i + 1):])
            cur.pop()

136. 只出现一次的数字

题目:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
示例:

输入: [2,2,1]
输出: 1

输入: [4,1,2,1,2]
输出: 4

解题前,首先需要熟知 3 个结论:

  • \(0 \oplus x = x\)
  • \(x \oplus x = 0\)
  • \((x \oplus y) \oplus z = x \oplus (y \oplus z)\)

这是异或的 3 个性质。回到本题,要求找出只出现 1 (或者说奇数次,本题方法依旧适用)。显然,只要某个 \(k\) 出现偶数次,所有的 \(k\) 异或结果是 0。对于出现奇数次的数字 \(x\),所有的 \(x\) 异或的结果是 \(x\)

只要理解了上面 3 个结论, 直接看代码:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int x = 0;
        for (auto k:nums)
        {
            x^=k;
        }
        return x;
    }
};

猜你喜欢

转载自www.cnblogs.com/sinkinben/p/12323784.html