最近刷到个网友吐槽挺扎心:40岁往上失业了,就别在招聘网站海投了,成功率跟我本地跑通一次“全绿CI”差不多稀有。评论区也很真实,有人说“过了40,简历像过期缓存,HR一键清理”;也有人反驳:“别吓人,我同学45靠项目经验回血。”

我觉得这话有点狠,但也戳到点:想再就业,路子大概就两条。要么你真是行业里能扛事的“大拿”,一上来就能把线上事故按住;要么有人内推,把你从“海量简历池”里捞出来。

招聘网站也不是没用,它更像打怪掉落的普通箱子,真正的金装,多半在圈子、作品、口碑里。你要真急,别只刷新投递记录,赶紧把能证明实力的东西摆出来,比“已投递99+”管用多了。

算法题 路径总和

那天在公司加班,脑子已经半糊涂了,结果同事跑过来一句: “东哥,那个…二叉树路径总和你懂吧?我 PHP 写着老是错。” 我当时整个人:?这不是面试题吗,怎么还追到工位来了。

先把题目捋一下哈,别一上来就撸代码。 就是给你一棵二叉树,每个节点有个 int 值,再给你一个 targetSum,问: 从根节点一路往下走到某个叶子节点,能不能找到一条路径,所有节点的值加起来刚好等于 targetSum。 注意两个坑:

  • 必须从根开始

  • 必须到叶子结束(左右孩子都为 的那种)

我当时脑子里第一个冒出来的画面是: 人从公司门口(根节点)出发,一路经过工位、茶水间、厕所…走到最里面那个“死胡同”办公室(叶子),看你路上花掉的时间能不能刚好等于 60 分钟下班时间。差一分都不行

这题其实就是个 DFS,深度优先,把路径上的值一路累加。说人话就是: 到一个节点,就扣掉它的值,看剩下的还差多少;走到叶子的时候刚好差 0,就说明 OK。

先写个最标准的递归版本,PHP 版,自己敲的,不是网上搬的:

php

classTreeNode{
public int $val;
public ?TreeNode $left;
public ?TreeNode $right;

publicfunction__construct(int $val = 0, ?TreeNode $left = , ?TreeNode $right = ){
$this->val = $val;
$this->left = $left;
$this->right = $right;
}
}

functionhasPathSum(?TreeNode $root, int $targetSum): bool
{
// 空树,肯定没有
if ($root === ) {
returnfalse;
}

// 到叶子了,就看差不差这一个值
if ($root->left === && $root->right === ) {
return $targetSum === $root->val;
}

// 往下递归,targetSum 每下一层就减掉当前节点
$leftHas = hasPathSum($root->left, $targetSum - $root->val);
$rightHas = hasPathSum($root->right, $targetSum - $root->val);

return $leftHas || $rightHas;
}

你看逻辑其实很直白对吧:

  1. 根是空的,那你还求个啥路径。

  2. 如果已经是叶子节点,那就“对答案”:当前 targetSum 和叶子值一比,相等就成功。

  3. 否则就把“剩下要凑的和”往孩子那边传,谁能凑出结果就算谁赢。

我同事当时问我:“为啥你不在往下走的时候加和,而是 targetSum 一路减啊?” 因为这样写有两个好处:

  • 不用再额外传一个当前和的参数

  • 到叶子那一刻条件特别干净: $targetSum === $root->val ,不用再算

当然你要是非想写个“往上加”的版本也行,比如这样(就当多给你个对比写法):

functionhasPathSum2(?TreeNode $root, int $targetSum): bool
{
return dfs($root, 0, $targetSum);
}

functiondfs(?TreeNode $node, int $curSum, int $target): bool
{
if ($node === ) {
returnfalse;
}

$curSum += $node->val;

// 到叶子,看累计和是不是刚好
if ($node->left === && $node->right === ) {
return $curSum === $target;
}

return dfs($node->left, $curSum, $target)
|| dfs($node->right, $curSum, $target);
}

两个版本你随便选一个,面试的时候别两个都写,容易把自己绕晕… 我一般实战就用第一个“target 一路减”的,手感会更顺一点。

顺便吐槽一下,很多人这题栽在两个地方:

  • 没处理叶子条件 :只要和等于 target 就返回 true,结果中途路上就返回了,其实还没走到叶子,这就不符合题意。

  • PHP 的 判断写乱了 :一会儿 == ,一会儿 === ,还顺手来个 empty($node) ,看着就头大。

再啰嗦一句,如果你要在项目里用类似逻辑,比如权限树、菜单树里判断“有没有某条路径满足条件”,这个套路一模一样,换个变量名就行。 树这种东西嘛,就是: 当前节点干点事,然后把“剩下的问题”扔给孩子 。 会这一题,以后看到什么“路径总和 II”“任意路径总和 III”,就只是改改返回值、存个路径数组的问题了。

行了不说了,我去泡杯咖啡,你有别的算法题继续丢过来。