📅  最后修改于: 2023-12-03 15:34:53.318000             🧑  作者: Mango
本文将分享一位 SDE-1 的 GEP 面试经历,供各位程序员参考。该面试在校园内进行,主要考察了面试者的编程能力和解决问题的能力。
在第一轮面试中,面试官让面试者实现一个二叉树的遍历算法。具体来说,要求实现前序遍历、中序遍历、后序遍历以及层序遍历。面试官提供了一个二叉树节点的定义,并要求面试者手写代码实现这些遍历算法。
代码片段如下:
class TreeNode {
public:
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
vector<int> preOrder(TreeNode* root) {
vector<int> res;
if (!root) return res;
stack<TreeNode*> s;
s.push(root);
while (!s.empty()) {
TreeNode* node = s.top();
s.pop();
res.push_back(node->val);
if (node->right) s.push(node->right);
if (node->left) s.push(node->left);
}
return res;
}
vector<int> inOrder(TreeNode* root) {
vector<int> res;
if (!root) return res;
stack<TreeNode*> s;
TreeNode* node = root;
while (node || !s.empty()) {
while (node) {
s.push(node);
node = node->left;
}
node = s.top();
s.pop();
res.push_back(node->val);
node = node->right;
}
return res;
}
vector<int> postOrder(TreeNode* root) {
vector<int> res;
if (!root) return res;
stack<TreeNode*> s;
s.push(root);
while (!s.empty()) {
TreeNode* node = s.top();
s.pop();
res.insert(res.begin(), node->val);
if (node->left) s.push(node->left);
if (node->right) s.push(node->right);
}
return res;
}
vector<int> levelOrder(TreeNode* root) {
vector<int> res;
if (!root) return res;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
TreeNode* node = q.front();
q.pop();
res.push_back(node->val);
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
return res;
}
在第二轮面试中,面试官提供了一个已经实现好的程序,要求面试者分析该程序的时间复杂度,并且为该程序提供一个更优的算法。具体来说,该程序用两个数组 a
和 b
来表示一个矩阵,其中 a[i]
表示矩阵第 i
行第 1
列的元素,b[i]
表示矩阵第 1
行第 i
列的元素。程序的功能是计算矩阵的乘积。
原程序代码如下:
vector<vector<int>> matrixMultiply(vector<int>& a, vector<int>& b, int n) {
vector<vector<int>> c(n, vector<int>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int k = 0; k < n; k++) {
c[i][j] += a[i*n+k] * b[k*n+j];
}
}
}
return c;
}
面试者经过分析得出该程序的时间复杂度为 $O(n^3)$,并提供了一个更优的算法。
优化后的代码片段如下:
vector<vector<int>> matrixMultiply(vector<int>& a, vector<int>& b, int n) {
vector<vector<int>> c(n, vector<int>(n));
vector<int> row(n, 0);
for (int i = 0; i < n; i++) {
for (int k = 0; k < n; k++) {
row[k] = a[i*n+k];
}
for (int j = 0; j < n; j++) {
int sum = 0;
for (int k = 0; k < n; k++) {
sum += row[k] * b[k*n+j];
}
c[i][j] = sum;
}
}
return c;
}
面试者将矩阵的行存储在一个数组中,这样可以避免重复访问 $a$ 数组中的元素,从而提高了算法的效率。新的算法的时间复杂度为 $O(n^2)$。
在第三轮面试中,面试官让面试者解决一个算法问题。具体来说,面试者需要找出一个字符串中出现次数最多的字符。如果有多个字符出现次数相同,则返回其中任意一个即可。
面试者使用哈希表记录每个字符出现的次数,并遍历哈希表找到出现次数最多的字符。面试官对此算法给予了好评,并询问面试者如何处理字符串中的空格。面试者回答可以将空格视为一个特殊字符来处理。
代码片段如下:
char mostFrequentChar(string& s) {
unordered_map<char, int> freq;
int maxFreq = 0;
char maxChar = ' ';
for (char c : s) {
if (c == ' ') {
freq[c]++;
} else {
freq[c]++;
if (freq[c] > maxFreq) {
maxFreq = freq[c];
maxChar = c;
}
}
}
return maxChar;
}
通过以上 SDE-1 的 GEP 面试经历,我们可以总结出一些有用的经验:
我们希望以上经验能够对各位程序员在面试过程中提供一些参考和帮助。