整数反转 --- 开始刷题2
关于 -- 整数反转 Reverse Integer,例如 123,翻转为321关于这个题的难点分析1、负数处理GO语言中 % 和 / 对负数的行为与数学直觉一致保留符号这其实是好事不需要特殊处理符号位。2、溢出判断最关键题目要求不能存储64位整数。这意味着我们不能先翻转成 int 64 在判断是否超过 int 32 范围。必须在反转过程中用int 32 就能预判“下一步会不会溢出”。在此之前需要梳理/ 是整数除法向零截断当两个整数相除时Go的 / 会直接丢弃小数部分只保留整数。在数学上叫做“向零取整”Truncation toward zero。表达式数学结果Go 结果说明123 / 1012.312正数向下截断 ✅-123 / 10-12.3-12负数向上截断朝零方向⚠️7 / 23.53正数正常截断-7 / 2-3.5-3不是 -4是朝零方向Python的整数除法是“向下取整”floor,-7//2-4。但go是向零截断-7/2 -3。% 是取余不是严格的“取模”Go 的 % 更准确的说是“取余”Remainder,而不是数学意义上的“取模”Modulo。两者的区别在于负数时的符号Go的规则; a%b 的结果符号永远与a 被除数相同。表达式Go 结果说明123 % 103正数正常-123 % 10-3负数结果带负号7 % 31正常-7 % 3-1不是 2跟随被除数符号这两个特性很重要我们用来反转算法即用 % 来得到最低位用 / 来去掉最低位以 x -123 为例验证一致性第一轮 当前 x -123pop x % 10 -123 %10 -3 --- 得到了原始数字的个位 3带符号x x / 10 -123 /10 -12 ---- 去掉了个位得到了剩下的-12rev rev * 10 pop 0*10 (-3) -3 ---- 反转结果目前个位 reverse 就是反转第二轮当前 x -12pop x % 10 -12 % 10 -2 --- 得到了原始数字的十位 2x x / 10 -12 / 10 -1 ----去掉了十位得到了剩下的 -1rev rev * 10 pop (-3)*10 (-2) -32 ---- 十位也被拼上去了第三轮循环当前 x -1pop x % 10 -1 % 10 -1 --- 得到原始数字的 百位 1x x / 10 -1 / 10 0 ---- 去掉最后一位得到x 变成了0rev rev * 10 pop (-32)*10 (-1) -321 --- 百位也被拼上了反转完成循环结束 x 0 --- 退出循环返回 rev -321每次*10就把之前已经拼好的所有数字整体左移一位给新来的数字腾出个位空间。这本质上就是一个“边取边构建”的过程天然完成了反转完全不需要额外的存储空间。每次砍掉最低位后原来的十位就变成了新的个位下次 %10 自然就取到了它。这就是整数反转算法的妙处。还需要去了解和表示 2的31次方-1以及 -2的31次方maxInt32 131 - 1 // 2147483647 minInt32 -1 31 // -2147483648131 -1 和 -1 31 具体的来源这个是位运算Bitwise Operation,直接对应计算机底层存储整数的方式补码Twos Complement。32位有符号整数在内存中长这样共 32个bit最高位第31位符号位。 0 正数 1 负数低31位数值位1、maxInt32 131 - 1 --- 2147483647131 的含义把数字 1 左移 31位 针对有符号表示最高位表示的是符号 当没有符号的时候1左移31位即2的31次方即2147483648 二进制1000 0000 0000 0000 0000 0000 0000 0000 代表的是2147483648 但是现在有符号所以有符号的32位最大值为2的31次方减一 131 的含义把数字 1 左移 31位 再减一 二进制 0111 1111 1111 1111 1111 1111 1111 1111 (int32: 2147483647) 最高位的0符号位代表正数 十进制21474836472、minInt32 -1 32-1 31 -1 的补码32位全1: 二进制 1111 1111 1111 1111 1111 1111 1111 1111 左移 31 位低位补0: 二进制 1000 0000 0000 0000 0000 0000 0000 0000 十进制 -2147483648------------------------- 这个先学到这明天补充剩下的逻辑