371. 两整数之和

371. 两整数之和

371. 两整数之和

我的思路

既然无法用加法,那么是不是可以用汇编add(笑)?

class Solution {
public:
    int getSum(int a, int b) {
        __asm {
                mov eax, a
                mov ebx, b
                add eax, ebx
                mov a, eax
            };
        return a;
    }
};

很不幸,Visual studio可以编译通过,LeetCode提交编译错误。

直觉:二进制。(直觉是一种很玄的东西)

如果是无进位加法的话,结果是两个数字的亦或,即 r e t = a ⨁ b ret = a \bigoplus b ret=ab.

然后,差一步思考。

思路一

既然无进位加法是 a ⨁ b a \bigoplus b ab, 那么只需要思考进位该如何处理即可。

假设当前需要相加的两个二进制位是: a , b a, b a,b. 当前位的结果为:低一位的进位 c a r r y carry carry + a + b a + b a+b. 同时,需要向高一位进位。设当前位是第 i i i 位。

  • a == 1 && b == 1 时,当前位需要向前面的一位进位,当前位的结果等于低位的进位: ret |= (carry << i),当前位的进位是1
  • a == 1 || b == 1 时,当前位的结果是低位的进位和1的异或: ret |= ((1 ^ carry) << i),进位不需要变化。(可以自己模拟一下)
  • a == 0 && b == 0 时,当前位的结果是低位的进位:ret |= (carry << i),当前位的进位是0

因为在整形范围内,因此执行最多执行32次即可完成。

AC代码:

class Solution {
public:
    int getSum(int a, int b) {
        int carry = 0;
        int ret = 0;
        for (int i = 0; i < 32; i ++){
            int _a = (a >> i) & 1;
            int _b = (b >> i) & 1;
            if (_a == 1 && _b == 1){
                ret |= (carry << i);
                carry = 1;
            }else if (_a == 1 || _b == 1){
                ret |= ((1 ^ carry) << i);
            }else{
                ret |= (carry << i);
                carry = 0;
            }
        }
        return ret;
    }
};

时间复杂度: O ( 1 ) O(1) O(1),执行32次。
空间复杂度: O ( 1 ) O(1) O(1),使用了可数个变量。

思路二

假设两个数字为6(100b)和13(1101b)。这两个数字的加法可以变成:1.无进位加法:6 ^ 13,2.进位:6 & 13,3.进位左移:(6 & 13) << 1,4.将低位的进位和当前无进位结果相加。

在 C++ 的实现中,当我们赋给带符号类型一个超出它表示范围的值时,结果是 undefined;而当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模的余数。因此,我们可以使用无符号类型来防止溢出。

使用unsigned int防止溢出。

AC代码:

class Solution {
public:
    int getSum(int a, int b) {
        while (b){
            unsigned int carry = (unsigned int)(a & b) << 1;
            a ^= b;
            b = carry;
        }
        return a;
    }
};

时间复杂度分析:因为每一次左移都会将低位的0增加,因此最多执行32次,carry就会变成0. O ( 1 ) O(1) O(1).
空间复杂度分析: O ( 1 ) O(1) O(1)


2021.09.27 10:27

9.21号至9.25号的2022级研究生复试面试秘书A的工作结束了,有点小累。

昨天和周老师聊了一下,下午就从科工楼搬到了天际大厦。

离别总是太匆匆,都来不及说告别。

正式开启打工人的生活,不只是工位发生了变化,研究方向也转向区块链了。

慢慢来吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1000以内所有各位数字之和为n的正整数为: - 当n = 1时:1, 2, 3, 4, 5, 6, 7, 8, 9 - 当n = 2时:11, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61, 70, 71, 80, 81, 90, 91 - 当n = 3时:101, 110, 111, 120, 121, 130, 131, 140, 141, 150, 151, 160, 161, 170, 171, 180, 181, 190, 191, 200, 201, 210, 211, 220, 221, 230, 231, 240, 241, 250, 251, 260, 261, 270, 271, 280, 281, 290, 291, 300, 301, 310, 311, 320, 321, 330, 331, 340, 341, 350, 351, 360, 361, 370, 371, 380, 381, 390, 391 - 当n = 4时:1001, 1010, 1011, 1020, 1021, 1030, 1031, 1040, 1041, 1050, 1051, 1060, 1061, 1070, 1071, 1080, 1081, 1090, 1091, 1100, 1101, 1110, 1111, 1120, 1121, 1130, 1131, 1140, 1141, 1150, 1151, 1160, 1161, 1170, 1171, 1180, 1181, 1190, 1191, 2000, 2001, 2010, 2011, 2020, 2021, 2030, 2031, 2040, 2041, 2050, 2051, 2060, 2061, 2070, 2071, 2080, 2081, 2090, 2091 - 当n = 5时:10001, 10010, 10011, 10020, 10021, 10030, 10031, 10040, 10041, 10050, 10051, 10060, 10061, 10070, 10071, 10080, 10081, 10090, 10091, 10100, 10101, 10110, 10111, 10120, 10121, 10130, 10131, 10140, 10141, 10150, 10151, 10160, 10161, 10170, 10171, 10180, 10181, 10190, 10191, 11000, 11001, 11010, 11011, 11020, 11021, 11030, 11031, 11040, 11041, 11050, 11051, 11060, 11061, 11070, 11071, 11080, 11081, 11090, 11091 - 当n = 6时:100001, 100010, 100011, 100020, 100021, 100030, 100031, 100040, 100041, 100050, 100051, 100060, 100061, 100070, 100071, 100080, 100081, 100090, 100091, 100100, 100101, 100110, 100111, 100120, 100121, 100130, 100131, 100140, 100141, 100150, 100151, 100160, 100161, 100170, 100171, 100180, 100181, 100190, 100191, 101000, 101001, 101010, 101011, 101020, 101021, 101030, 101031, 101040,这是1000以内所有各位数字之和为n的正整数的列表。每个n对应的列表中都包含了所有各位数字之和为n的正整数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值