某员工吐槽:同事偷偷给我介绍私活,说1万报酬全给我,结果甲方私下告诉我同事在当中白拿了2万,媳妇却让我要知足,说我一点不亏
刚刷到个帖子,给我看得一愣一愣的。哥们本来以为是同事仗义,私活介绍过来,张口就是“1万都给你,我不拿”。
结果甲方转头一句实话,直接把底裤掀了:人家在中间白拿了2万。你说这事最气人的还不是他赚了,是他一边赚,一边还演得跟活菩萨似的,真有点膈应。
更绝的是,回家一说,媳妇来一句“你也没亏啊,知足吧”。这话也不能说全错,钱确实到手了,活也不是白干,但人心这个账真不是这么算的。
你以为碰到贵人,结果是黄牛,还得自己劝自己别上头,想想都无语。
算法题:最大回文数乘积
两个三位数一乘,答案不一定大,但想要“最大回文数乘积”,暴力写歪了,跑起来是真慢。
这题我第一眼一般不急着把 100 到 999 全乘一遍。不是不能做,是没必要。你真把双重循环老老实实跑满,代码当然也能过,但这种写法没什么手感,像是机器在抡,没带脑子。
先盯住两件事:
第一,回文数怎么判断。这个简单,转字符串反转一下就行,Python 干这个很顺手。 第二,怎么少乘点。既然要找最大值,那外层和内层都应该从大往小扫;而且一旦当前乘积已经不可能超过现有答案,后面那一串就没继续算的意义了,这里直接剪枝。
先看一个够用的版本:
defis_palindrome(n: int) -> bool:
s = str(n)
return s == s[::-1]
deflargest_palindrome_product() -> int:
best = 0
for a in range(999, 99, -1):
if a * 999 < best:
break
for b in range(999, a - 1, -1):
product = a * b
if product <= best:
break
if is_palindrome(product):
best = product
break
return best
print(largest_palindrome_product())
这里有两个小动作挺关键。
一个是 if a * 999 < best。 比如当前 a 已经降到某个值了,拿它去乘最大的 999,连现有答案都超不过,那这个 a 后面的组合就全不用看了。
另一个是内层的 if product <= best。 因为 b 是从大到小走,后面只会更小,乘积也只会更小,继续跑纯属浪费 CPU。
这题最后答案是 906609,对应的是 913 * 993。
当然,还有人喜欢先“造回文数”,再反推能不能拆成两个三位数相乘。那个思路也行,理论上更漂亮一点,但这题没必要上来就拧那么大。面试或者笔试里,先把一个剪枝清楚、复杂度明显收住的版本写出来,更稳。
再补一个我不太喜欢但很多人会顺手写出来的版本:
best = 0
for a in range(100, 1000):
for b in range(100, 1000):
val = a * b
if str(val) == str(val)[::-1]:
best = max(best, val)
这段的问题不是错,而是笨。 它把对称的乘法全算了两遍,像 913 * 993 和 993 * 913,结果一样,白跑一次。而且没有任何提前停止的意识,属于数据范围一大就容易露怯的写法。
所以这题真正该写出来的,不只是“我会判断回文”,而是你得让人看出你知道从哪下刀能少做事。