Python技术迷

某员工吐槽:同事偷偷给我介绍私活,说1万报酬全给我,结果甲方私下告诉我同事在当中白拿了2万,媳妇却让我要知足,说我一点不亏

刚刷到个帖子,给我看得一愣一愣的。哥们本来以为是同事仗义,私活介绍过来,张口就是“1万都给你,我不拿”。

结果甲方转头一句实话,直接把底裤掀了:人家在中间白拿了2万。你说这事最气人的还不是他赚了,是他一边赚,一边还演得跟活菩萨似的,真有点膈应。

Image

更绝的是,回家一说,媳妇来一句“你也没亏啊,知足吧”。这话也不能说全错,钱确实到手了,活也不是白干,但人心这个账真不是这么算的。

你以为碰到贵人,结果是黄牛,还得自己劝自己别上头,想想都无语。


算法题:最大回文数乘积

两个三位数一乘,答案不一定大,但想要“最大回文数乘积”,暴力写歪了,跑起来是真慢。

这题我第一眼一般不急着把 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,结果一样,白跑一次。而且没有任何提前停止的意识,属于数据范围一大就容易露怯的写法。

所以这题真正该写出来的,不只是“我会判断回文”,而是你得让人看出你知道从哪下刀能少做事。