月薪2万,在大厂干了10年被裁了,拿了30万赔偿金,五年后HR联系我,问我愿不愿意回去,但要归还30万,这种情况该回去吗?
刚看到个贴子:楼主月薪2万在大厂干了10年,被裁拿了30万赔偿。五年后原公司HR来电话,说可以回去,但得把当年的赔偿吐出来,问值不值得回。
网友回复挺分裂的,有人说30万本来就是人家“施舍”,现在愿意再要你就偷着乐;也有人觉得这公司没底线,让你退钱说明压根没把员工当人看。
我觉得这事关键在一个字:值。赔偿是当年合法给你的,不存在“借”这一说,除非公司现在给到远高于市场的待遇和职位,你自愿把那30万当做“投资”,否则真没必要。换个角度想,五年里你如果有本事在别处混得不错,那说明你不缺这家大厂;如果这些年一直不顺,跟其说是回厂,不如说是给自己一个重新起步的机会。
力
算法题:有效的井字游戏
我直接说结论啊:这道“有效的井字游戏”,本质就是——别被棋盘骗了,只看两件事:落子数合不合理、胜负结果合不合理,就完事了。
那天晚上加班,到点了还在等一个接口压测结果,我就拿白板随手画了个井字棋跟小同事对划。画着画着他突然问我一句:“东哥,要是给你一个最终棋盘,让你判断这个局面是不是游戏过程中能走出来的,你咋写?”
我一想,咦,这不是正儿八经的算法题嘛,在 LeetCode 里就叫:有效的井字游戏(Valid Tic-Tac-Toe State)。
题目长这样,简单说人话就是:
棋盘 3x3,用字符串数组 board = ["XOX"," XO"," "]这种表示X先手,两个人轮流下,只有X和O两种子有人三连(横竖斜都算)就赢了,游戏可以提前结束 问你:现在这个棋盘,有没有可能是按规则一手一手下出来的
你想啊,真实对局里有个最铁的规则:轮流下,也就是:
因为 X先手,所以X的个数要么比O多 1,要么刚好一样多不可能出现 O比X多,也不可能X比O多 2 个以上
翻成代码就是先扫一遍棋盘:
x_count = sum(row.count('X') for row in board)
o_count = sum(row.count('O') for row in board)
# 数量不对,直接假
if o_count > x_count:
returnFalse
if x_count - o_count > 1:
returnFalse
到这,所有“摆造型”的假棋盘,比如全是 O、或者 X 一排 O 一排那种,都能先筛掉一大半。
数完子以后,就要问一句:有没有人已经三连了?
这时候写个小函数就行,八条线挨个检查:三行、三列、两条对角线。
defwin(ch: str) -> bool:
b = board
# 三行
for i in range(3):
if b[i][0] == b[i][1] == b[i][2] == ch:
returnTrue
# 三列
for j in range(3):
if b[0][j] == b[1][j] == b[2][j] == ch:
returnTrue
# 两条斜线
if b[0][0] == b[1][1] == b[2][2] == ch:
returnTrue
if b[0][2] == b[1][1] == b[2][0] == ch:
returnTrue
returnFalse
有了 win('X') 和 win('O') 之后,接下来几个坑一定要卡住:
两个人不可能同时赢
真对局里,只要有人先三连,游戏就结束了,不会再给另一个人下出一条三连线 所以: if x_win and o_win: return False如果是 X 赢了
说明最后一步一定是 X 下的 所以 此时必须满足: x_count == o_count + 1否则就是“赢完了还让 O 多下了一手”,假局面 如果是 O 赢了
最后一步是 O 下的 所以必须: x_count == o_count不然就变成 O 落后还赢,违背轮流规则 如果谁都没赢
那就只看数量关系: 前面已经保证过 x_count == o_count或x_count == o_count + 1,那就可以认为是合法过程中的某一帧
整个逻辑串起来其实就几句判断,但一堆人挂在“赢了之后还能继续下几步”这种边界上。
上完整代码,直接能跑,用的是 Python,类型注解你爱写就写,不写也行:
from typing import List
classSolution:
defvalidTicTacToe(self, board: List[str]) -> bool:
# 1. 统计 X 和 O 的个数
x_count = sum(row.count('X') for row in board)
o_count = sum(row.count('O') for row in board)
# 轮流规则:X 先手,X 要么等于 O,要么多 1
if o_count > x_count:
returnFalse
if x_count - o_count > 1:
returnFalse
# 2. 判断某个玩家是否已经三连
defwin(ch: str) -> bool:
b = board
# 行
for i in range(3):
if b[i][0] == b[i][1] == b[i][2] == ch:
returnTrue
# 列
for j in range(3):
if b[0][j] == b[1][j] == b[2][j] == ch:
returnTrue
# 对角线
if b[0][0] == b[1][1] == b[2][2] == ch:
returnTrue
if b[0][2] == b[1][1] == b[2][0] == ch:
returnTrue
returnFalse
x_win = win('X')
o_win = win('O')
# 3. 胜负与落子数是否匹配
# 不可能双方都赢
if x_win and o_win:
returnFalse
# X 赢:必须比 O 多下一手
if x_win and x_count != o_count + 1:
returnFalse
# O 赢:必须和 X 手数相同
if o_win and x_count != o_count:
returnFalse
# 其他情况就是合法局面
returnTrue
你可以自己随便构造几个棋盘试试,比如:
["XXX","OO "," "]→ X 三连了,而且 X=3, O=2,合法["XXX","OOO"," "]→ 双方都赢了,直接判假["XOX"," X "," "]→ 数量不满足(O 太少或太多)也会被前面挡掉
这类题的套路啊,说白了就是:把游戏规则拆成几条 if,然后死磕边界,别想一口气写个“超聪明”的神奇公式。
行了,我先去泡杯咖啡,你要是后面想练习别的博弈类题,比如四子棋、五子棋那种判断胜负的,我们再慢慢唠。