堂弟 45岁,今年被裁员了,赔偿金18万,被裁后他找了半年的工作,都嫌弃他年龄大,工资比以前少大半,不够养家~
刚看到个贴子,说一位45岁的堂弟被裁了,拿了18万赔偿,半年求职处处碰壁,现在想着把家里凑的40万干点小生意。嗯…这事儿挺现实的。
我看了看网友的回复,有说“年龄歧视没办法”,也有鼓励他创业的。但我觉得吧,创业这东西,不能因为找不到工作就当成退路。
换个角度想,小生意就像摆摊卖煎饼,看着简单,其实每个环节都要本事,40万真不算多,亏起来比下雨还快。
在我看来,关键不是靠不靠谱,而是他有没有准备好。做什么?懂不懂?能不能扛得住?如果只是为了脱困而冲动创业,那风险比被裁还大。现在哪怕找份收入少点的工作,先稳住现金流,再慢慢摸索方向,也比把老本全压上要稳。
不过话说回来,人到中年确实不容易,能重新站起来就值得鼓励。【备注:文末可领最新资料】
面试题:在二叉树中增加一行
在公司加班到十一点多,脑子已经有点浆糊了,结果群里有人丢过来一道题:“在二叉树中增加一行”,还点名说要用 Python 写。我一看,这不是面试常考的那道嘛,干脆顺手给你也讲一遍,顺便当复习。
一、题目到底在干嘛?
先把问题说人话一点:
给你一棵二叉树 root,一个整数 val 和一个深度 depth。 要求是在「第 depth 层」插入一整行节点,每个新节点的值都是 val。
规则是这样的:
原来在第 depth 层的那些节点,要整体“下沉”到新加的这一层下面。
更具体点:
原来的 node.left 变成新左节点的 left 原来的 node.right 变成新右节点的 right 然后把新建的这两个节点挂回到 node.left / node.right 对于每个在第 depth-1 层的节点 node:
还有一个特殊情况:
如果 depth == 1,那就要在整棵树的最上面加一行,也就是说新建一个值为 val 的节点,把原来的 root 当成它的左子树,新节点变成新的根。
示意一下(非常粗糙的那种):
原来:
1
/ \
2 3
如果 val = 9,depth = 2,插完变成:
1
/ \
9 9
/ \
2 3
左边那颗旧子树挂到新 9 的 left,右边那颗挂到新 9 的 right。
二、怎么找“插在哪一层”?
思路其实挺直接的,关键点只有一个:把所有“在 depth-1 层的节点”找出来,然后在它们下面插新行。
所以整体可以拆成两步:
如果 depth == 1:特殊处理,直接新建根节点。 否则:找到所有在 depth-1 层的节点,对每个节点做一次“左右各插一个”的操作。
那怎么找 depth-1 层呢?常规有两种写法:
BFS(层序遍历):一层一层往下走,数层数,走到 depth-1 就停。 DFS(递归):递归参数带当前层数,当层数 == depth-1 时处理当前节点。
两种都可以,我个人平时写题更偏向 BFS,因为“按层操作”的题用队列写起来比较直观,不容易绕晕。
三、用 BFS 写一版(队列层序遍历)
核心操作就是“走到 depth-1 层,然后对这一层所有节点动手”。
先假设我们有一个标准的二叉树节点定义:
# 二叉树节点定义(跟常见题目一样)
classTreeNode:
def__init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
正式代码:
from collections import deque
classSolution:
defaddOneRow(self, root: TreeNode, val: int, depth: int) -> TreeNode:
# 特殊情况:在第 1 层加一行 => 新根节点
if depth == 1:
new_root = TreeNode(val)
new_root.left = root
return new_root
# 普通情况:用 BFS 找到第 depth-1 层
queue = deque()
queue.append(root)
current_depth = 1
# 先走到 depth-1 层
while queue and current_depth < depth - 1:
level_size = len(queue)
for _ in range(level_size):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
current_depth += 1
# 此时 queue 里面就是所有 depth-1 层的节点
while queue:
node = queue.popleft()
# 先保存旧的左右子树
old_left = node.left
old_right = node.right
# 建新的左节点和右节点
node.left = TreeNode(val)
node.right = TreeNode(val)
# 把原来的子树挂到新节点下面
node.left.left = old_left
node.right.right = old_right
return root
你可以顺着逻辑走一遍:
depth == 1:直接把旧 root 挂到新节点左边,返回新根,OK。
depth > 1:
把原来的左右子树备份一下, 新建两个节点挂在左右, 再把刚刚备份的左右子树接到新节点下面。 while 那一段是“往下走层数”,走到 current_depth == depth-1 停。
停的时候,队列里全是 “这一层” 的节点。
对每个节点:
其他层完全不动。
时间复杂度: 整棵树最多访问一次,所以是 O(N),N 为节点数。
空间复杂度: 队列最多装一层的节点,最坏情况接近 O(N),平均也是 O(N)。
四、要不要用 DFS?
顺便提一句 DFS 的写法,大概就是:
定义一个递归函数 dfs(node, current_depth) 当 current_depth == depth-1 时,对 node 做同样的“插左右”操作 否则就递归 node.left 和 node.right
意思一样,只是写法风格不同。给你个参考代码(不用也行,看个思路):
classSolutionDFS:
defaddOneRow(self, root: TreeNode, val: int, depth: int) -> TreeNode:
if depth == 1:
new_root = TreeNode(val)
new_root.left = root
return new_root
defdfs(node, current_depth):
ifnot node:
return
if current_depth == depth - 1:
old_left = node.left
old_right = node.right
node.left = TreeNode(val)
node.right = TreeNode(val)
node.left.left = old_left
node.right.right = old_right
else:
dfs(node.left, current_depth + 1)
dfs(node.right, current_depth + 1)
dfs(root, 1)
return root
这版就更“递归党友好”一点,看个人习惯。
五、一些小坑顺便提一下
随便提醒几个容易脑抽的点:
depth == 1 一定要单独处理,否则你会发现根本没机会往上插一层。 修改左右指针的时候,一定要先把旧的 left/right 保存下来,不然直接覆盖掉就找不回了。 不管 BFS 还是 DFS,别忘了空节点的判断,不然容易空指针。
整体来说,这道题逻辑不复杂,就是“按层操作 + 特殊的 depth=1”,多写几遍就很顺手了。
差不多就这样,我去泡杯咖啡压压惊,你要是想顺带练习下“构造二叉树 + 打印层序”那一套,也可以跟我说,我可以顺便给你拼一份完整的测试脚手架。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB