2019 年亚马逊面试体验(SDE-1 校内)
亚马逊于 2019 年 2 月在我们的大学进行了一个游泳池安置。我们分享了在 HackerEarth 上托管的测试的链接,其中包含 20 个 MCQ(来自 GeeksQuiz 的技术 - 操作系统、数据库、TOC 等)和 2 个具有部分截止的编程问题.
预赛
- 平铺问题
- 给定一个 ab2c3 形式的字符串重复了很多次,您应该找到字符串的第 K 个字符。例如:ab2c3 => ababc2 => ababcababc
第1轮:
面试官很友好,他让我放松一下。他浏览了我的简历,并询问了我在黑客马拉松上构建的应用程序以及它们是如何工作的。之后他给了我一个简单的问题。
- 给定一个正整数和负整数数组,如果数组中存在 +x 和 -x,则打印 x。我要求澄清是否应该打印所有不同的x或者如果遇到一对+x和-x是否应该打印 x 。我告诉的第一种方法是使用地图,如果找到一次,我会为+x和-x保留一个标志。后来他让我打印所有对,所以我将所有元素的频率存储在地图中并遍历负元素,对于每个元素x ,我会打印x min(count[-x],count[+x] )次。他说他买不起那么多空间,他希望我进一步优化空间。所以我告诉他一个 2 指针方法,我对数组进行一次排序,然后保留两个指针指向开始和结束。如果总和小于 0,我会将开始指针向前移动,如果总和大于 0,我将向后移动结束指针。他对解决方案很好,并要求我在论文中对其进行编码。我编写了代码并引导他完成了它。
- 在像“Splitwise”这样的应用程序中设计最小化现金流的逻辑。在这里,面试官告诉我一个叫 splitwise 的应用程序,我用过一次。在应用程序中,每个用户都会添加他花费的金额以及该应用程序的其他用户如何共享这些金额。目的是尽量减少给予和接受操作的次数。我最初想到了一种非常幼稚的方法,我想为每个人和支出创建类,并遍历其他人的支出以找出一个人应该付出或接受多少。当我仔细观察时,我想到了将其建模为有向图并为事务添加有向边的想法。通过该图,我考虑了两个人之间的一对边之间的差异,以将给予和接受操作减少到单个给予/接受操作。有一个问题,如果 A 必须给 B Rs.10,B 必须给 C Rs.10,A 必须给 C Rs.10,那么最少的操作是从 A 给 C.Rs.20。 B在这里没有参与,因为他必须花掉他得到的所有东西。所以我说我们可以用传入和传出边上的数字对图形进行预处理。如果总流量为 0,我们可以删除该节点。他似乎对这种方法深信不疑。在完成所有预处理后,他给了我一张图表,最后问我如何最小化它。所以我使用了贪婪的方法。我正在通过给予必须给予较少金额的人的数量来解决必须获得最大金额的人的数量,他说这会奏效。
第 2 轮:
在这一轮开始的时候,面试官问了我一些我知道的数据结构。链表、树、图表、数组等是我的答案。他问我对动态编程了解多少。我说我在这方面并不强,他说他肯定会问我一个关于动态编程的问题。
- 给定一棵通用树,找出所有特殊节点的计数。如果存在从根到具有所有不同元素的节点的路径,则节点是特殊节点。输入不是指向树的指针。他会给我一个邻接列表和一个值数组,其中邻接列表中第 i 个节点的值是值数组中的第 i 个元素。他要求我不要从给定的信息中创建一棵树,而是使用邻接列表本身。我建议进行深度优先搜索,保留一个集合,其中包含到给定节点的所有元素。一旦我到达一个特定的节点,我会检查它是否已经在集合中。如果它已经在集合中,我会返回,因为该元素已经被访问过并且不是特殊节点。否则,我将全局变量的计数增加 1 并将该元素推送到集合中。然后我遍历那个元素的邻接列表并递归调用这个函数。一旦我在访问它的邻居后从元素返回,我从 set 中弹出元素。我告诉他接近了,他让我为它写代码。他对这种方法深信不疑,并且喜欢该代码。
- 给定一个整数数组,找到相邻数字具有共同数字的最长子序列。例如:1 12 44 29 33 96 89。这里最长的子序列是 {1 12 29 96 89},答案是 5。我最初尝试了 2D DP 解决方案,其中 dp[i][j] 表示最长序列的长度,以 i 结尾,包含 j 作为数字。这是一个 NX 10 DP 矩阵。面试官问我为什么需要 2D DP 解决方案,我很难说服他。我为它写了代码。这并不完全正确。我错过了一些东西。经过一段时间的思考,我缩小到一个只包含 10 个元素的解决方案 dp[0], dp[1], dp[2].. dp[9] 每次我看到一个新数字时都会更新。我取一个数字,遍历数字中的所有数字,并找到 val = 1 + max(dp[d] for all digits d in the number) 。对于数字中的所有数字,将此 val 设置为 dp[d]。他暗示要取最大值。
虽然没有一点提示也无法完全解决,但我对自己前进的方向充满信心,并不断与面试官互动。我被选中进入下一轮。
第三轮:
面试官问我到目前为止是否对面试过程感到满意,以及之前的面试情况如何。我说很好,他给了我第一个要解决的问题。
- 给定一棵二叉树,修改满足以下约束的树:
- 根的值必须是左孩子和右孩子(不是子树)的总和。
- 您不能减少任何节点的值。你只能增加它。
- 根节点的值必须是最小值。我画了几棵树,问他这些例子的输出。他让我自己说,我照做了。我想做一个后序遍历,因为我们需要在访问 root 之前访问 root 的左右 chlid。在后序遍历中,我们将根的左右孩子之和保存在一个变量 sum 中。我们取这个总和与根数据的差。如果总和大于根的数据,我们将根替换为总和。否则,我们必须将根的值分配给根的左右孩子,以便满足所有三个条件。 (我们不能减少任何节点的值)。他让我为它编写代码,我做到了。之后他又给了我一个问题。
- 给定一个由 0、1 和 2 组成的数组,在一次迭代中对该数组进行排序。
- 在浏览器中输入 URL 时网页如何显示?
我解决了这两个问题并为它们编写了代码。面试官问了我的项目。他专注于我完成的一个机器学习项目,并问了很多关于它的问题。我被选中进入下一轮。
第四轮:
本轮面试官问了我一些CS基础知识以及一些行为问题。
- 线程和进程之间的区别。
- 死锁及其预防
- OOP 中的多态性成本
- 虚拟方法、动态绑定、vtables等的实现
- 集合和映射之间的实现差异。
- 压缩尝试
- 实现一个 Trie 数据结构并编写函数以在其中插入和搜索几个单词。我编写了一个类来使用节点向量作为子节点来实现字符Trie。他要求我改进空间。因此,仅当存在子节点时,我才使用哈希图来存储子节点。我编写了插入代码并找到了一个单词并引导他完成。
- 检查两个单词是否是字谜。 我首先通过对两个字符串进行排序并比较它们来实现它。他让我写一个更好的方法。所以我使用了一个hashmap来做到这一点。
- 一些行为问题,例如如果您最近加入并且您的老板不在岗位上您会怎么做,您的朋友会如何评价您(好与坏),为什么选择亚马逊等。
与前几轮相比,这一轮难度很大。在与整个小组讨论后,他们从驱动器中雇用了两个。我就是其中之一。