【Leetcode】26.只出现一次的数字III(位运算)

题目链接

点击打开链接

题目描述

【Leetcode】26.只出现一次的数字III(位运算)_第1张图片

题解

两个位运算

  1. 异或:
    两个相同的数异或结果为0;0和任意值异或结果为那个数。
  2. x&(-x):
    结果为x的二进制位的最后一位。

    举个例子(第一位为符号位):
    10 -> (0 00000…000 1010)b
    -10 -> (1 11111…111 0110)b
    负数的二进制变换方式是:1. 按位取反。 2. 末位加1。
    这时两个数进行与运算,结果就是 (0 0000.0000 10)b。

解题思路

  1. 所有数做异或运算,这时得到的结果表示:x和y的异或的结果(设x和y为结果,其它的数在异或的时候出现了2次,变成了0)。结果也可以理解为二进制位上为1的位置,就是x和y不同的位置,这个二进制位上,要么x为1,要么y为1。
  2. 对这个二进制位上为1的数再求一遍异或。就可以得到其中的一个数。
  3. 把得到的这个数和第1步求得的异或求异或,就得到了第2个数。

代码

/*
 * @lc app=leetcode.cn id=260 lang=cpp
 *
 * [260] 只出现一次的数字 III
 */

// @lc code=start
class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int diff = 0;
        for (int n: nums)
            diff ^= n;
        int bit = diff&(-diff);  // 取二进制最后一个1
        
        int x = 0;
        for (int n: nums)
        {
            if (n&bit)  // 这一位为1
                x ^= n;
        }
        return {x, diff^x};
    }
};

你可能感兴趣的:(Leetcode刷题,位运算)