计算类

130 阅读2分钟

定理类

最大公约数

—— 辗转相除法(欧几里得法)

int a, b,r;
if(a < b) swap(a,b);
do{
    r = a % b;
    a = b;
    b = r
   }while(r);//answer is a

最小公倍数

—— 公式法:两个数的乘积 = 最大公约数 * 最小公倍数

大整数

大整数加法

655 · 大整数加法

    string addStrings(string &num1, string &num2) {
        // write your code here
        if(num1.empty()) return num2;
        if(num2.empty()) return num1;
        int len1 = num1.size();
        int len2 = num2.size();
        string res = "";
        
        int len = len1>len2 ? len1 : len2;
        while(len1 > len2)
        {
            num2 = '0' + num2;
            len2++;
        }
        while(len1 < len2)
        {
            num1 = '0' + num1;
            len1++;
        }
        int c_i = 0;
        for(int i = len - 1; i >= 0; i--)
        {
            int sum = c_i + (num1[i] - '0') + (num2[i] - '0');
            if(sum >= 10)
            {
                sum = sum % 10;
                c_i = 1;
                res = to_string(sum) + res;
            }
            else
            {
                c_i = 0;
                res = to_string(sum) + res;
            }    
        }
        if(c_i == 1) res = '1' + res;
        return res;
    }
};

key point

  1. 补齐字符串
  2. 模拟竖式计算

大整数乘法

656 · 大整数乘法

二进制求和

67. 二进制求和 思路同大整数求和,只是在判断条件处不同。

位运算

137. 只出现一次的数字 II


int singleNumber(vector<int>& nums) {
        /*
         <--- 2^i
         4 3 2 1 0
        -----------
    num: 1 0 0 1 0
         1 1 0 1 0
         1 0 0 1 0
         1 0 0 1 0
        -----------
         1 0 1 1 0
         1 0 0 1 0
         1 0 1 1 0
         1 0 1 1 0
        */
        int ans = 0;
        for(int i = 0; i < 32; i++)
        {
            int total = 0;
            for(auto num : nums)
            {
                total += ((num>>i) & 1);
            }
            if(total % 3)
            {
                ans |= (1<<i);
            }
        }
        return ans;
    }

key point

这个思路太重要了,之前完全没有涉及过。

为了方便叙述,我们称「只出现了一次的元素」为「答案」。

由于数组中的元素都在int(即32位整数)范围内,因此我们可以依次计算答案的每一个二进制位是0还是1。

具体地,考虑答案的第 i个二进制位(i从 0开始编号),它可能为 0 或 1。对于数组中非答案的元素,每一个元素都出现了 3 次,对应着第 ii 个二进制位的 33个 0 或 3 个 11,无论是哪一种情况,它们的和都是 3 的倍数(即和为 0 或 3)。因此:

答案的第 i 个二进制位就是数组中所有元素的第 i 个二进制位之和除以 3 的余数。

这样一来,对于数组中的每一个元素 x,我们使用位运算 (x >> i) & 1 得到 x 的第 i 个二进制位,并将它们相加再对 3 取余,得到的结果一定为 0 或 1,即为答案的第 i 个二进制位。

260. 只出现一次的数字 III

看官方解析吧,目前为止还没搞懂。