2024-09-13 update
已经收到意向了,没想到结果却是好的,此事也算了结。
前前后后花了约莫一个月,夜夜辗转反侧,此中滋味实在是不足为外人道也。
Timeline:
- 08/16 一面
- 08/20 二面
- 08/26 三面
- 09/04 hr面
- 09/13 意向
好像呼应了早先文末的一句“塞翁失马焉知非福”,实习面试的失败却意外促成了秋招面试的成功,也算某种意义上的“世事难料”。
细碎念头很多,但今天却实在不想动笔,想太多倒也无用,未来怎么样就交给未来吧🙂。
记录沉痛的失败
1. Failure 1
今年4月找实习的时候被XX捞了,好不容易整到了二面,刁难人的智力题也回答来了,但倒在了手撕上:
- 0-1背包问题
- 腐烂的橘子
- 大数乘法
- 二叉树的右视图
其实在这个时间点已经把hot100刷完了,还另外多刷了七八十道,想着手撕怎么也得优势在我
,万万没想到tmd刷错了题单🤡。
我刷的是所有题目中的题单LeetCode 热题 HOT 100
,实际上hot100指的是LeetCode 热题 100,但这里的2. 4.两道手撕都只在后者里才有。
到这里已经暴露了两个问题:
- 和一起找实习的人交流过少,连leetcode刷错了都不知道
- 反应能力太差,二叉树的右视图不过是层序遍历取每一层的最后一个,当时太紧张没反应过来
但事后还没有仔细反省,整天乐乐呵呵的,于是就导致了第二次惨剧。
2. Failure 2
就在昨天,已经干到XX三面了,细细想来已经是第8次面XX了,没想到又倒在了手撕上:
- 相邻数字合并打印
- 快排递归改迭代
- 序列化和反序列化N叉树
- 大数乘法
前面两道磕磕绊绊倒是做出来了,第三道实在是不会(结束一查leetcode会员题,草),重点又是这该死的大数乘法
。
人不能在一个地方跌倒两次,自在上一次失败后,我把大数乘法的解法狠狠刻在大脑,没想到这次正好被我碰上了,于是十分钟不到就自信地撕出来了,但面试官一句不能用vector又将我打入深渊……
大数乘法在leetcode里是叫43. 字符串相乘
,题解中官方解法如下:
1class Solution {
2public:
3 string multiply(string num1, string num2) {
4 if (num1 == "0" || num2 == "0") {
5 return "0";
6 }
7 int m = num1.size(), n = num2.size();
8 auto ansArr = vector<int>(m + n);
9 for (int i = m - 1; i >= 0; i--) {
10 int x = num1.at(i) - '0';
11 for (int j = n - 1; j >= 0; j--) {
12 int y = num2.at(j) - '0';
13 ansArr[i + j + 1] += x * y;
14 }
15 }
16 for (int i = m + n - 1; i > 0; i--) {
17 ansArr[i - 1] += ansArr[i] / 10;
18 ansArr[i] %= 10;
19 }
20 int index = ansArr[0] == 0 ? 1 : 0;
21 string ans;
22 while (index < m + n) {
23 ans.push_back(ansArr[index]);
24 index++;
25 }
26 for (auto &c: ans) {
27 c += '0';
28 }
29 return ans;
30 }
31};
思路非常清晰:
- 从低位到高位依次相乘,将结果存在每一位应该在的位置,这里有个推论:第i位和第j位的乘积是在第i+j+1位
- 这里由于是用vector
来存,不用在乘法过程中考虑进位,后面专门有个for循环来处理进位 - 删除前导0,并收集结果
如此清晰易懂很难让人不学习,但忽略了使用string也可以达到相同的效果
:
1class Solution {
2public:
3 string multiply(string num1, string num2) {
4 if(num1 == "0" || num2 == "0") {
5 return "0";
6 }
7
8 int m = num1.size();
9 int n = num2.size();
10
11 string res(m + n, '0');
12
13 for (int i = m - 1; i >= 0; --i) {
14 int n1 = num1[i] - '0';
15 for (int j = n - 1; j >= 0; --j) {
16 int n2 = num2[j] - '0';
17 int n3 = res[i + j + 1] - '0' + n1 * n2;
18 res[i + j + 1] = n3 % 10 + '0';
19 res[i + j] += n3 / 10;
20 }
21 }
22
23 for (int i = 0; i < m + n; ++i) {
24 if (res[i] != '0') return res.substr(i);
25 }
26 return "0";
27 }
28};
这里思路大体相同,这里唯一要注意的是一个char类型本质上也是存的整数,所以可以处理超过10的进位,而不是只能存字符0-9
,但直到yp提醒我才发觉这一点,谢谢你yp。
我太蠢了,以前当助教总因为别人不懂怎么把数字和字符相互转换扣别人的分,直到今天我才发现真正应该被扣分的人是我啊🤡。
出来混,迟早要还,这下不但面试G了,还得泡池子被人按住当分母了😭,草!
3. 啊!失败
不过塞翁失马焉知非福?
- 突然跳出思维的陷阱让人在苦苦秋招的同时恍惚间有了一些实感
- 偶尔停下来思考也许能省去很多未来的烦恼
- 失败倒是让人放平心态,面对现实,不再逃避,毕竟哪有事事如意
说来说去好像都是一些细碎的念头,一边写一边遗憾地自娱自乐,不过好在如今都落在文字上也算进步,希望偶尔再看能提醒自己不再踩坑,继续前进。
人总是要长大。已经发生的事,已经没了的人,总是回头看也没用,只能把现在的事情做得漂亮点。
最后,谢谢你看到这里🙂,共勉!