面完十五分钟就接 offer了,hr还打电话给我读了很长一段用心的面试评价,很幸运
十五分钟面完就接 offer,这事听着都像职场爽文。更离谱的是,HR 还专门打电话过来,读了一大段面试评价,那种认真劲儿,打工人听完都得愣两秒:现在招聘市场还有这种待遇?
现在太多人找工作,简历投出去像扔进海里,能收到个“不合适”都算讲武德,更别提面完马上给结果,还附赠一段走心反馈。
这种体验最稀缺的,根本不是 offer 本身,是那种“我被认真对待了”的感觉。人一找工作久了,最先磨没的就是这点体面。碰上这种公司,哪怕后面不一定十全十美,起码开头没把人当流水线零件。打工人有时候图的,也就是这口气。
面
试
题
:
单调递增的数字
一眼看这个题,很多人会顺手上回溯,甚至想把所有小于等于
n
的数字都扫一遍。这个路子能做,但我一般不太信,数据一大就显得笨。
题目要找的是:给定一个非负整数
n
,返回小于等于它、并且各位数字单调递增的最大数字。像
1234
这种就算,
332
这种不算,因为
3 > 2
,后面掉下去了。
这题真正麻烦的地方,不在“怎么判断递增”,而在“发现某一位破坏递增后,前面到底该怎么改”。拿
332
举例,很多人第一反应是把最后那个
2
改大,或者把中间那个
3
改小一点就完事。其实都不对。这个题要的是
不超过 n 的最大值
,所以一旦某一位出现下降,正确动作不是修后面,而是先把前一位减 1,再把后面全部变成
9
。
比如:
-
332->329还不行,因为3 > 2 -
再往前退一位 ->
299 - 这时候就对了,而且还是最大
class Solution {
public int monotoneIncreasingDigits(int n) {
char[] arr = String.valueOf(n).toCharArray();
int mark = arr.length;
for (int i = arr.length - 1; i > 0; i--) {
if (arr[i - 1] > arr[i]) {
arr[i - 1]--;
mark = i;
}
}
for (int i = mark; i < arr.length; i++) {
arr[i] = '9';
}
return Integer.parseInt(new String(arr));
}
}
这段代码重点就两步。
第一步,从右往左扫。为什么不是从左往右?因为你一旦发现
arr[i - 1] > arr[i]
,说明前一位大了,得减 1。但前一位减完,未必还能和更前面保持递增,所以要继续往左检查。这个地方如果从左往右写,后面还得反复回退,代码会别扭很多。
第二步,记录一个
mark
。从这个位置开始,后面的数全部改成
9
。原因很直接:前面既然已经退了一步,后面当然要尽可能大,才能保证结果最大。
拿
1234
跑一下,没有任何一位出问题,
mark
不变,结果还是它自己。
拿
10
跑一下:
-
1 > 0,前面减一,变成0 -
后面补
9 -
得到
09,转成整数就是9
120
跑一下:
-
2 > 0,变成110,并记录位置 -
继续看
1和1,没问题 -
后面补
9 -
结果
119