某大厂员工:月供0.44元,在职场上已经没有弱点了。不再是被领导拿捏的对象
月供四毛四,这种人你还怎么拿捏。
以前公司里最怕哪种人?不是脾气大的,也不是能力最强的,是那种对工资真没那么上头的人。房贷几乎等于没有,生活成本又压得住,领导画饼,他听着;领导施压,他也听着,但心里大概就一句:哦,然后呢?
网友说得挺损,说这已经不是“上班”,这是来公司体验人类社会。还有人说,一旦没了房贷车贷孩子补习班三件套,职场PUA立马失效一大半。你仔细一想,还真是。
会开会,但不内耗;会干活,但不表忠心;真惹急了,大不了找下家。
说白了,职场里最硬的底气,很多时候不是title,是账单够不够轻。领导最怕的,也从来不是刺头,是那种随时能把工牌一摘,晚上照样睡得香的人。
面试题:打家劫舍
那种一眼看上去像“隔一个偷一个”的思路,写到“打家劫舍”这题基本都会翻车。因为你抢了第 i 家,下一家就不能碰;你不抢第 i 家,前面的最优结果还得留下来。这个题没什么花活,本质就是一路做选择:当前这家,到底拿不拿。
最容易写错的地方,不是在状态定义,而是在脑子里总想把“当前金额最大”理解成“当前这家必须抢”。这两个不是一回事。dp[i] 表示的是:走到第 i 家时,前 i 家房子里你最多能拿多少钱,至于第 i 家抢没抢,不重要。
转移就一句话:
不抢第 i 家:那就是 dp[i - 1]抢第 i 家:那就得接上 dp[i - 2] + nums[i]
两者取大。
这个题我一般都不先上数组,先把状态压成两个变量,写起来更顺,也更像线上代码里会保留的样子。
publicclassRobberSolver{publicintrob(int[] nums){if (nums == null || nums.length == 0) {return0; }int prev2 = 0; // 到前前一家时的最优解int prev1 = 0; // 到前一家时的最优解for (int money : nums) {int current = Math.max(prev1, prev2 + money); prev2 = prev1; prev1 = current; }return prev1; }publicstaticvoidmain(String[] args){ RobberSolver solver = new RobberSolver();int[] nums = {2, 7, 9, 3, 1}; System.out.println(solver.rob(nums)); // 12 }}拿 2,7,9,3,1 过一遍就很清楚了。
第一家抢,最多 2。 第二家和第一家冲突,只能在 2 和 7 里选,结果是 7。 第三家一进来,情况变了:如果抢 9,就要接前前家的 2,总共 11;如果不抢,就保持前面的 7,所以这里取 11。 后面也是一样滚过去,最后答案 12。
这题为什么经典?因为它把动态规划里最重要的一件事掰得很直白:你不是在想“这一家怎么处理”,你是在想“走到这里,历史最优怎么延续”。一旦状态定义对了,代码就很短。状态定义一歪,后面补再多判断都别扭。
时间复杂度是 O(n),空间复杂度是 O(1)。这种题在面试里不算难,但很能看出基本功。尤其是你能不能把“当前选择”和“阶段最优”分开,这是很多人一开始绕不过去的坎。