Python技术迷

相亲才认识两个月就定了婚期,感觉好恍惚,这周要去拍婚纱照,六月份就要结婚,彩礼15万

两个月,相亲对象直接升级成结婚对象,这速度搁公司里都算火箭晋升了。

婚纱照这周拍,六月份办酒,彩礼15万,男方全款房加名,女方再添点钱买车带回来。账一摊开,流程齐得像项目排期,唯独人还是懵的。

Image

评论区也挺真实。有人说,相亲本来就不是谈感觉,是谈条件,差不多就推进。还有人说,恍惚才正常,真等你缓过神来,孩子都会打酱油了。

但我看这事最扎心的不是快,是快得特别像在办手续。条件对上了,双方家里点头了,日子一排,婚就结了。你说有没有感情,可能也有,但更多像是先把坑位占上。

成年人到这一步,浪漫经常是最后才补票的。反正外人看着像喜事,当事人脑子里估计还在转:我这就真要结了?

算法题:给表达式添加运算符

表达式这题,看着像回溯,真写起来最容易翻车的地方不是“怎么搜”,而是怎么剪枝。

题目一般是这样的:给你一个只包含数字的字符串 num,再给一个目标值 target,要求往字符串里加 +、-、*,拼出所有结果等于 target 的表达式。比如 num = "123",target = 6,那结果里就有 1+2+3 和 1*2*3。

这题我第一眼就不太信那种“先转后缀表达式再算”的写法。不是不能做,是没必要,路径一长,字符串拼接和表达式计算会缠在一起,代码写着就别扭。更稳的做法还是 DFS。

关键点有两个。

第一个,数字不能有前导 0。也就是说 "105" 里你可以取 "1"、"10"、"105",也可以取 "0",但不能取 "05"。这个地方不拦,结果直接乱。

第二个,乘法不能像加减一样直接往累计值上糊。比如当前表达式是 1+2,累计值是 3,如果后面接 *3,你不能算成 3*3=9,因为真正的值是 1+(2*3)=7。所以递归时得多带一个“上一个操作数” prev,这样乘法时可以把上一次加进去的数撤回来,再乘上当前数。

代码我按这个思路写一版,够用了:

defadd_operators(num: str, target: int):
    ans = []

defdfs(index: int, path: str, total: int, prev: int):
if index == len(num):
if total == target:
                ans.append(path)
return

for i in range(index, len(num)):
# 前导0直接截住
if i > index and num[index] == '0':
break

            cur_str = num[index:i + 1]
            cur = int(cur_str)

if index == 0:
                dfs(i + 1, cur_str, cur, cur)
else:
                dfs(i + 1, path + '+' + cur_str, total + cur, cur)
                dfs(i + 1, path + '-' + cur_str, total - cur, -cur)
# 乘法要撤销上一个数,再乘进去
                dfs(i + 1, path + '*' + cur_str, total - prev + prev * cur, prev * cur)

    dfs(0, "", 0, 0)
return ans


print(add_operators("123", 6))   # ['1+2+3', '1*2*3']
print(add_operators("105", 5))   # ['1*0+5', '10-5']

这题本质上就是“切字符串 + 枚举运算符”。难点从来不在回溯框架本身,而在状态设计。index 表示扫到哪了,path 表示当前表达式,total 表示当前结果,prev 专门处理乘法优先级。

还有个细节,很多人会想先把所有数字切分出来,再统一插运算符。也能做,但分两阶段通常更绕。因为你最后还是得处理乘法优先级,还不如在一层 DFS 里一次走完。