刚看到个贴子:有个网友月薪15k,跳槽面试随口要了25k,HR第二天直接说能给35k,结果他自己被吓得打了退堂鼓。
网友回复我看了看,一派说“这岗位肯定有坑”,另一派说“典型不自信,给你钱你都不敢要”。
怎么说呢,我觉得两边都别走极端。谈薪本来就是双方试探,你开25k,对方愿意加到35k,第一反应不是慌,而是搞清楚:这钱是正常工资,还是“风险费”“保密费”“背锅费”。
问清楚岗位职责、绩效目标、加班和出差强度,再对照一下自己的本事,差多少,能不能在可控时间内追上去。
觉得匹配,就当这是市场给你的“抬轿”,大胆上;觉得完全不合适,也可以体面说不。
别一边想拿高薪,一边又把自己吓退。
今日算法题 你一个 32 位有符号整数 x ,把它的“数字部分”倒过来,比如:
123 变成 321
-456 变成 -654
120 变成 21 (前面的 0 要自动消失)
但是,有个关键条件: 结果必须还在 32 位有符号整数范围内 ,也就是 [-231, 231-1]。 一旦反转之后“超界”,就直接返回 0。
你看,麻烦就出在这个“超界”两个字上。
大部分人第一眼想到的就是字符串套路,对吧:
把整数转成字符串
处理一下负号
把数字部分反转
把反转后的字符串再转回数字
最后判断一下有没有溢出
逻辑很顺,但有几个小点容易被忽略:
负号要单独拿出来,不能一起反转 "123" 不能直接整个 reverse,不然就变成 "321" 了
前导零不用特意管,转回 int 的时候会自动消失
关键是:转回数字后,要确认是不是还在 32 位范围里 ,不在就返回 0
这个方法好处是直观、好写,坏处是有点“取巧”,而且在一些语言里频繁做字符串操作不算优雅(不过在算法题里完全能接受)。
如果你不想靠字符串,而是像写底层逻辑一样搞它,思路其实也很简单:
我们想把 x 的最后一位一位“抠出来”,拼到结果 res 的末尾。
整个过程就是循环做三件事:
digit := x % 10 拿到最后一位
x /= 10 原数去掉最后一位
res = res*10 + digit 拼到结果后面
比如 x = 123 :
第一次:digit=3, x=12, res=3
第二次:digit=2, x=1, res=32
第三次:digit=1, x=0, res=321
负数也一样,Go 里 % 和 / 对负数也能正常处理,比如 -123 % 10 == -3 ,逻辑是通的。
重点问题来了:溢出怎么判?
我们每次都会做这一步:
res = res * 10 + digit
如果这一行一执行就溢出,那程序就已经晚了。所以我们要在执行之前就判断: “再乘 10 再加一位,会不会超过 int32 的范围?”
32 位有符号整数的边界是:
intMax = 2147483647 // 2^31 - 1intMin = -2147483648 // -2^31
那我们在更新前检查:
如果 res > intMax / 10 ,那下一步肯定会溢出
如果 res == intMax / 10 ,那这次 digit 不能大于 7(因为最大值结尾是 7)
同理,负数这边:
如果 res < intMin / 10 ,也必溢
如果 res == intMin / 10 ,那这次 digit 不能小于 -8(最小值结尾是 8)
只要发现下一步会溢,就直接返回 0 就行了。
来,上代码。我们用 Go 写一个完整函数,顺便加个 main 跑一下,方便你本地试:
package mainimport ("fmt")const (intMax = 1
你可以自己试几个值:
123 → 321
-456 → -654
120 → 21
1534236469 这种反转后会超范围的,就会被乖乖处理成 0
注意几点小细节:
函数参数用的是 int ,但我们按 32 位的边界来判断就够了
不需要额外用 int64 ,因为我们在“将要溢出”之前就提前返回了
digit 是 int ,跟 7 和 -8 比较没问题
行,整数反转这个小玩意儿差不多就这些点: 核心就两个字:拆位 + 防溢出。
你先把上面那段 Go 代码敲一遍,别光截屏收藏,真动手的时候你会发现很多小细节是纸上看不出来的。
我先去弄杯咖啡,你要是想接着整别的算法题,比如回文数、罗马数字转整数那一挂的,咱们下一题接着聊。
虎哥私藏精品
虎哥作为一名老码农,整理了全网最全 《 GO后端开发资料合集 》。 总量高达 650GB 。
本站是社保查询公益性网站链接,数据来自各地人力资源和社会保障局,具体内容以官网为准。
定期更新查询链接数据 苏ICP备17010502号-11