拼夕夕员工爆料:有个哥们中了696万的彩票, 中奖当天就提了离职,已经有人开始去他“曾经”的工位打卡了
刚看到个贴子:说拼多多有个哥们中了696万,当天直接提离职,结果现在已经有人跑去他“曾经”的工位排队打卡拍照,跟景点似的。
网友们的回复我看了看,有羡慕的,说“换我我连老板微信都删了”;也有酸的,说“这种人肯定守不住钱”;还有人感叹“打工人最大的梦想就是一夜不用打工”。
我觉得这事吧,说白了就是:大家都太累了,才会把彩票当出口。真有人中了奖,像给所有打工人打了一针“幻想强心剂”。但话说回来,696万确实多,可真要躺平一辈子也未必够,尤其在一线城市。
与其天天幻想中彩票,不如把这种“爽感”拆开来用:该攒钱攒钱、该学习学习、该跳槽跳槽。彩票是极小概率,但让自己值钱是大概率。
面试题:旋转数字
我那天晚上十一点多,在公司楼下干啃冷掉的外卖,刷到这道“旋转数字”。
题意简单说下(常见的那个版本):
给你一个整数 n,统计从 1 到 n 之间,有多少个数字满足:
把数字每一位都绕着中点旋转 180°,还是一个有效数字 转完之后,这个数字和原来的不一样
旋转的规则是这样的:
0、1、8:转完还是自己 2 ↔ 5 互换 6 ↔ 9 互换 3、4、7:这仨直接废了,转完根本不是数字
比如:
1 → 1(没变,不算) 2 → 5(变了,算) 11 → 11(没变,不算) 12 → 15(变了,算) 38:有 3,直接判死刑,压根不是旋转数字
这个题最关键的就是写一个判断函数,判断“这个数是不是合法的旋转数字”。
思路特别像老师查作业:
从个位开始一位一位看
只要出现 3、4、7,立刻判不及格,直接 false
看完所有位以后,如果所有位都合法,但从来没出现过 2/5/6/9,说明转完和原来一模一样,也不算
只有同时满足:
没有 3/4/7 至少有一位是 2/5/6/9 才算好数
用 Java 写出来,大概这样:
publicclassRotatedDigits{
// 判断一个数是不是“旋转后合法而且变样”的数字
privatestaticbooleanisGood(int num){
boolean diff = false; // 是否出现过会变化的数字:2/5/6/9
while (num > 0) {
int d = num % 10;
// 1. 出现 3 / 4 / 7,直接不合法
if (d == 3 || d == 4 || d == 7) {
returnfalse;
}
// 2. 出现 2 / 5 / 6 / 9,说明旋转后一定会变
if (d == 2 || d == 5 || d == 6 || d == 9) {
diff = true;
}
num /= 10;
}
// 3. 没出现 3/4/7,且至少有一位是 2/5/6/9
return diff;
}
}
这个函数就是整题的心脏,逻辑只有两行: “碰到 3/4/7 直接挂掉;至少要有一位 2/5/6/9 才算合格”。
题目要求的是:统计 1 到 n 里有多少个这样的数。
最直接的办法就是:
从 1 循环到 n 每个数扔进 isGood里检测一下结果 count++就完事了
完整代码这样写:
publicclassRotatedDigits{
publicintrotatedDigits(int n){
int count = 0;
for (int i = 1; i <= n; i++) {
if (isGood(i)) {
count++;
}
}
return count;
}
// 判断是否为“旋转数字”
privatebooleanisGood(int num){
boolean diff = false;
while (num > 0) {
int d = num % 10;
if (d == 3 || d == 4 || d == 7) {
returnfalse;
}
if (d == 2 || d == 5 || d == 6 || d == 9) {
diff = true;
}
num /= 10;
}
return diff;
}
// 随便测一下
publicstaticvoidmain(String[] args){
RotatedDigits rd = new RotatedDigits();
System.out.println(rd.rotatedDigits(10)); // 预期 4 -> 2,5,6,9
System.out.println(rd.rotatedDigits(20));
}
}
复杂度怎么算呢?也简单:
外层从 1 到 n,一共 n 次 每次检查一个数的位数,最多就 5~6 位那种(n 一般不会给到特别离谱)
整体就是 O(n * 位数),在常见题目给的范围里,完全够用。 我之前让我们组那个小李写这题,他还想上什么“数位 DP”,结果一看数据范围,默默删掉重写了个 for 循环版……
如果你哪天刷到加强版,n 特别大,比如上到 10^9,那上面这种直接枚举会有点慢,就可以玩一玩数位 DP,大概思路是:
从最高位往下递归
状态里记:
当前到第几位 有没有出现过“会变化”的数字 前缀是否已经卡死在上界(tight) 每一位只能选合法数字(0、1、2、5、6、8、9),同时维护“是否出现过 2/5/6/9”
不过大多数面试/刷题场景,这题普通版本用上面那段简单 Java 就够交差了,面试官主要看的是:能不能把规则捋清楚,写成干净的判断逻辑,而不是一上来炫技。
行,我这边先说到这,回头要是你想练一下数位 DP 版本的,我再帮你把那个状态也拆一遍。