位运算

不用加减乘除做加法运算
转载:krahets

解题思路:

本题考察对位运算的灵活使用,即使用位运算实现加法。
设两数字的二进制形式 \(a,b\),其求和\(s=a+b\)\(a(i)\) 代表\(a\) 的二进制第\(i\) 位,\(b(i)\) 代表\(b\) 的二进制第\(i\) 位则分为以下四种情况:

\(a(i)\) \(b(i)\) 无进位和\(n(i)\) 进位\(c(i+1)\)
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

观察发现,无进位和异或运算 规律相同,进位与运算 规律相同(并需左移一位)。因此,无进位和 \(n(i)\)与进位\(c(i+1)\)的计算公式如下;

\[\left\{\begin{matrix}n=a \bigoplus b \\c=a \&b \ \ \end{matrix}\right. \]

\((和S) = (非进位和n)+(进位 c)\),即可将\(s=a+b\)转换为

\[s=a+b=>s=n+c \]

循环求\(n\)\(c\),直至进位\(c=0\),此时\(s=n\),返回\(n\)即可

Picture1.png

class Solution
{
public:
    int add(int a, int b)
    {
        while (b != 0)
        {
            int c = (unsigned int) (a & b) << 1;
            a ^= b;
            b = c;
        }
        return a;
    }
};

复杂度分析:

  • 时间复杂度 O(1)
  • 空间复杂度 O(1)

只出现一次的数字
异或运算满足交换性

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        for(int i=1;i<nums.size();i++)
            nums[0]^=nums[i];
        return nums[0];
    }
};
posted @ 2020-08-24 13:02  周颖  阅读(41)  评论(0)    收藏  举报