某大厂程序员:高中同学聚会,混的最好就俩人。我,大厂3-1,年薪百万;另一个老家省厅副处级,能平起平坐么?
这哥们是不是在大厂待久了,真把职级当官阶了。
高中同学聚会,聊谁混得好很正常,吹两句工资也没啥。年薪百万,3-1,放在打工人里确实不差,已经能让一桌人多夹两筷子菜了。
但你非要拿这个去跟省厅副处比“平起平坐”,味儿一下就不对了。
大厂再高,本质还是公司里的螺丝钉,只是这颗螺丝钉镀了点金。今天项目好,股票好,绩效好,你风光;明天组织一调整,老板换个口味,工牌都可能凉半截。
副处那边不是工资单好不好看的问题,人家是在体制内爬出来的位子,资源、稳定性、圈层,根本不是一个赛道。
所以网友怼得也狠:谁给你的勇气?真觉得“年薪百万”这四个字一摆,啥桌都能坐上主位。
反转字符串,别上来就 new 一个新字符串
["h","e","l","l","o"] 要变成 ["o","l","l","e","h"]。
这个题第一眼很简单,简单到不少人会直接写:
StringBuilder sb = new StringBuilder(str);
return sb.reverse().toString();
写业务代码这么干没啥问题,赶工的时候我也不会嫌弃它。
但算法题不一样。题目要你反转的是字符数组,而且通常会强调:原地修改,不要额外开数组。
这时候再 new 一个对象,就有点不讲武德了。
这题我一般就看两件事:
第一,能不能想到左右指针。
第二,边界会不会写乱。
代码就几行:
classSolution{
publicvoidreverseString(char[] text){
if (text == null || text.length < 2) {
return;
}
int left = 0;
int right = text.length - 1;
while (left < right) {
char tmp = text[left];
text[left] = text[right];
text[right] = tmp;
left++;
right--;
}
}
}
这段代码没什么花活。
left 从左边走,right 从右边走,两边字符交换。交换完之后,左指针右移,右指针左移。直到两个指针碰头,或者交错,就停。
拿 "hello" 跑一下:
h e l l o
^ ^
o e l l h
o e l l h
^ ^
o l l e h
中间那个 l 不用管,长度是奇数的时候,它本来就在最终位置上。
有些人这里会写成:
while (left <= right)
这个我不太喜欢。
不是说一定错,奇数长度时中间字符自己跟自己交换一次,结果也对。但没必要。算法题里多做一次无意义操作,虽然不至于超时,但习惯不好。你写多了,后面碰到链表、数组窗口这种题,很容易把边界搞炸。
再看空数组和单字符:
char[] a = {};
char[] b = {'x'};
这两种直接 return。即使不写前面的判断,right = length - 1 后,循环也不会进去。但我一般还是留着这句:
if (text == null || text.length < 2) return;
原因很简单,业务代码里传 null 太常见了。算法平台可能不传,线上接口可不一定。
这个题真正要记住的不是“反转字符串”这几个字,而是这个交换模型:
while (left < right) {
swap(left, right);
left++;
right--;
}
数组反转、回文判断、旋转数组的一部分,都会反复用到它。
比如判断一个字符数组是不是回文,只是把“交换”换成“比较”:
booleancheckPalindrome(char[] text){
if (text == null) {
returnfalse;
}
int left = 0;
int right = text.length - 1;
while (left < right) {
if (text[left] != text[right]) {
returnfalse;
}
left++;
right--;
}
returntrue;
}
这个题不用递归。
递归当然能写,但没必要。每递归一层都要压栈,字符串长一点就不划算。面试里写递归版,除非题目明确要求,否则我会觉得你在把简单题复杂化。
反转字符串这题,能用两个指针原地交换写干净,就够了。边界别抖,别额外开数组,别为了炫技把代码绕远。真正线上排问题的时候,最怕的就是这种本来三行能看懂的逻辑,被写成一坨“很聪明”的代码。