📜  亚马逊面试经历 | 348 组(用于 SDE II)(1)

📅  最后修改于: 2023-12-03 15:36:05.704000             🧑  作者: Mango

亚马逊面试经历 | 348 组(用于 SDE II)

简介

亚马逊是一家全球电子商务巨头,是时下最为火爆的互联网公司之一,拥有众多用户。亚马逊的技术水平和开发体系都很先进,而其招聘流程及面试形式也备受关注。

在亚马逊备受青睐的 SDE II 这一职位中,面试一般分为以下几个环节:

  1. 电话面试
  2. (至少)3 轮在线代码语言选择测试
  3. (至少)3 轮通话面试
  4. (至少)2 轮面试与现场面试

其中,在线测试与通话面试是必须参加的环节,所以这两个部分我们会从语言选择与常见问题出发,帮助面试者更好地准备。

在线代码语言选择测试

亚马逊的在线测试选择部分,也即 Hackerrank 测试,是调查求职者熟练掌握编程语言的部分。通常,亚马逊要求 SDE II 具有 C++、Java 或 Python 中的至少两种语言的熟练使用能力。

因此,我们提供以下几个参考问题和解答,帮助大家更好地准备上述测试:

问题 1:用 C++/Java/Python 写一个链表的反转函数

C++ 代码:

ListNode* reverseList(ListNode* head) {
    ListNode *pre = nullptr, *curr = head;
    while (curr) {
        ListNode *nt = curr->next;
        curr->next = pre;
        pre = curr;
        curr = nt;
    }
    return pre;
}

Java 代码:

public ListNode reverseList(ListNode head) {
   ListNode pre = null;
   ListNode curr = head;
   while (curr != null) {
       ListNode nt = curr.next;
       curr.next = pre;
       pre = curr;
       curr = nt;
   }
   return pre;
}

Python 代码:

def reverseList(self, head: ListNode) -> ListNode:
    pre, curr = None, head
    while curr:
        nt = curr.next
        curr.next = pre
        pre, curr = curr, nt
    return pre

以上三个版本的代码是比较基础、常见的链表反转函数的实现。考虑到时间限制和语言自带函数的利用,代码解答并不那么复杂,且注释阐明。

问题 2:用 C++/Java/Python 写一个并查集

并查集是一种基于树形结构的数据结构,主要用于处理“集合”类问题。在大型网络环境下,它的应用尤为频繁。

但无论是 Java 还是 Python,都没有自带的 union-find(并查集)库函数。因此,在面试时展示 掌握并查集算法是很重要的。

以 C++ 为例,我们可以使用以下代码实现并查集:

class UnionFindSet {
public:
    UnionFindSet(int n) {
        for (int i = 0; i < n; ++i) 
            _sets.push_back(i);
    }
    
    int find(int x) {
        if (_sets[x] != x) 
            _sets[x] = find(_sets[x]);
        return _sets[x];
    }
    
    void union_(int x, int y) {
        _sets[find(x)] = find(y);
    }
    
    bool isSame(int x, int y) {
        return find(x) == find(y);
    }
    
private:
    vector<int> _sets;
};
通话面试

在亚马逊的通话面试中,技术面试官会给求职者提出一些常见的面试问题,其中大多数与设计、数据结构及算法相关。下面,我们列举出常见的几类问题,并且给出它们的解答。

问题 1:用数组实现一个队列

这是一道很常见的问题,大多数程序员都很熟悉。对于亚马逊的面试官,他们通常想检验求职者的编程能力以及对队列和数组的理解。

class Queue {
public:
    Queue(int capacity) {
        head = 0;
        tail = 0;
        this->capacity = capacity;
        this->queue = new int[capacity];
    }

    bool push(int x) {
        if (tail == capacity) {
            if (head != 0) {
                int i = head;
                while (i < tail) {
                    queue[i - head] = queue[i];
                    ++i;
                }
                tail = tail - head;
                head = 0;
            } else {
                return false;
            }
        }
        queue[tail++] = x;
        return true;
    }

    int pop() {
        if (head == tail) return -1;
        return queue[head++];
    }

    bool empty() {
        return head == tail;
    }

private:
    int head;
    int tail;
    int capacity;
    int* queue;
};

该类的主要组成部分有构造函数、add()(增加操作)、poll()(删除操作)、empty()(判空操作)。在这里,我们判断队列是否已经满了,如果满了就对列头部分出列,把添加的数据插入到尾部。

问题 2:求一个链表的中间节点

这道题主要考察双指针(快慢指针)算法,关于该算法,实在是不能再经典。我们先在列表上使得 fast 指针遍历的速度是 slow 的两倍,当 fast 指针到达列表的末尾时,slow 指针就指向了列表的中间元素。

ListNode* getMiddleNode(ListNode* head) {
    ListNode *slow = head, *fast = head;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}
问题 3:判断一个二叉树是否是平衡二叉树

要想判断一个二叉树是否是平衡二叉树,我们只需要判定每个节点左右子树的高度差是否大于 1 即可。通常,我们可以用递归的方式来求出每个节点左右子树的高度。

同时,判定高度时,我们需要提供一个初始条件 NULL,以处理二叉树为空的情况。

bool isBalanced(TreeNode* root) {
    if (root == NULL) return true;
    if (abs(depth(root->left) - depth(root->right)) > 1) return false;
    return isBalanced(root->left) && isBalanced(root->right);
}

int depth(TreeNode* root) {
    if (root == NULL) return 0;
    return max(depth(root->left), depth(root->right)) + 1;
}
总结

在本篇文章中,我们列举了亚马逊 SDE II 面试的在线测试与通话面试部分,希望大家可以通过了解这些部分的内容,更好地准备和规划自己的求职面试过程。