headPic

记两次失败的面试

OAP

2024-09-13 update

已经收到意向了,没想到结果却是好的,此事也算了结。

前前后后花了约莫一个月,夜夜辗转反侧,此中滋味实在是不足为外人道也。

Timeline:

  • 08/16 一面
  • 08/20 二面
  • 08/26 三面
  • 09/04 hr面
  • 09/13 意向

好像呼应了早先文末的一句“塞翁失马焉知非福”,实习面试的失败却意外促成了秋招面试的成功,也算某种意义上的“世事难料”。

细碎念头很多,但今天却实在不想动笔,想太多倒也无用,未来怎么样就交给未来吧🙂。

记录沉痛的失败

1. Failure 1

今年4月找实习的时候被XX捞了,好不容易整到了二面,刁难人的智力题也回答来了,但倒在了手撕上:

  1. 0-1背包问题
  2. 腐烂的橘子
  3. 大数乘法
  4. 二叉树的右视图

其实在这个时间点已经把hot100刷完了,还另外多刷了七八十道,想着手撕怎么也得优势在我,万万没想到tmd刷错了题单🤡。

我刷的是所有题目中的题单LeetCode 热题 HOT 100,实际上hot100指的是LeetCode 热题 100,但这里的2. 4.两道手撕都只在后者里才有。

到这里已经暴露了两个问题:

  1. 和一起找实习的人交流过少,连leetcode刷错了都不知道
  2. 反应能力太差,二叉树的右视图不过是层序遍历取每一层的最后一个,当时太紧张没反应过来

但事后还没有仔细反省,整天乐乐呵呵的,于是就导致了第二次惨剧。

2. Failure 2

就在昨天,已经干到XX三面了,细细想来已经是第8次面XX了,没想到又倒在了手撕上:

  1. 相邻数字合并打印
  2. 快排递归改迭代
  3. 序列化和反序列化N叉树
  4. 大数乘法

前面两道磕磕绊绊倒是做出来了,第三道实在是不会(结束一查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};

思路非常清晰:

  1. 从低位到高位依次相乘,将结果存在每一位应该在的位置,这里有个推论:第i位和第j位的乘积是在第i+j+1位
  2. 这里由于是用vector来存,不用在乘法过程中考虑进位,后面专门有个for循环来处理进位
  3. 删除前导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. 啊!失败

不过塞翁失马焉知非福?

  • 突然跳出思维的陷阱让人在苦苦秋招的同时恍惚间有了一些实感
  • 偶尔停下来思考也许能省去很多未来的烦恼
  • 失败倒是让人放平心态,面对现实,不再逃避,毕竟哪有事事如意

说来说去好像都是一些细碎的念头,一边写一边遗憾地自娱自乐,不过好在如今都落在文字上也算进步,希望偶尔再看能提醒自己不再踩坑,继续前进。

人总是要长大。已经发生的事,已经没了的人,总是回头看也没用,只能把现在的事情做得漂亮点。

最后,谢谢你看到这里🙂,共勉!

end

Previous post

再会南昌

Next post

C++: functional