📜  亚马逊面试经历 |设置 397(校内)(1)

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

亚马逊面试经历 |设置 397(校内)

洛谷题目

我参加了亚马逊举办的校内面试,其中有一道洛谷题目,题目如下:

给定一个长度为n的整数序列a1, a2, ..., an,在保证序列中所有数都不相同的前提下,对每个1<=i<=n,找出序列中从i开始,第一个大于ai的数的下标j(j > i)。若不存在这样的j,则令j = 0。要求时间复杂度O(nlogn)。

我使用了离线处理的方法,详见 洛谷题解

编程题目

除了洛谷题目,还有其他编程题目。其中一个题目是要实现一个简单的高精度计算器。我使用了C++语言,通过手写大整数类实现了加、减、乘、除以及取模等操作。虽然是一个简单的计算器,但是需要考虑边界情况和错误处理。我的实现代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 10010;

struct BigInteger {
    int len, num[N];
    BigInteger() {
        len = 1;
        memset(num, 0, sizeof(num));
    }
    BigInteger(int number) { // 将整数转化为大整数
        len = 0;
        while (number) {
            num[++len] = number % 10;
            number /= 10;
        }
        if (!len) len = 1;
    }
    BigInteger(string str) { // 将字符串转化为大整数
        len = str.length();
        for (int i = 0; i < len; i++) {
            num[len - i] = str[i] - '0';
        }
    }
    BigInteger operator + (const BigInteger& b) const { //加法
        BigInteger res;
        res.len = max(len, b.len) ;
        for (int i = 1; i <= res.len; i++) {
            res.num[i] += num[i] + b.num[i];
            res.num[i + 1] += res.num[i] / 10;
            res.num[i] %= 10;
        }
        while (res.num[res.len + 1] > 0) res.len++;
        return res;
    }
    BigInteger operator - (const BigInteger& b) const {//减法
        BigInteger res;
        res.len = len;
        for (int i = 1; i <= len; i++) {
            res.num[i] = num[i] - b.num[i];
            if (res.num[i] < 0) {
                res.num[i] += 10;
                num[i + 1]--;
            }
        }
        while (res.len > 1 && res.num[res.len] == 0) res.len--;
        return res;
    }
    BigInteger operator * (const BigInteger& b) const {//乘法
        BigInteger res;
        res.len = len + b.len - 1;
        for (int i = 1; i <= len; i++) {
            for (int j = 1; j <= b.len; j++) {
                res.num[i + j - 1] += num[i] * b.num[j];
            }
        }
        for (int i = 1; i <= res.len; i++) {
            res.num[i + 1] += res.num[i] / 10;
            res.num[i] %= 10;
        }
        while (res.num[res.len + 1] > 0) res.len++;
        while (res.len > 1 && res.num[res.len] == 0) res.len--;
        return res;
    }
    BigInteger operator / (const BigInteger& b) const {//除法
        BigInteger res, a = *this;
        res.len = max(len - b.len + 1, 1);
        for (int i = res.len; i >= 1; i--) {
            int l = 0, r = 9;
            while (l < r) {
                int mid = (l + r + 1) >> 1;
                if (b * BigInteger(mid) <= a) l = mid;
                else r = mid - 1;
            }
            res.num[i] = l;
            a = a - b * BigInteger(l);
        }
        while (res.len > 1 && res.num[res.len] == 0) res.len--;
        return res;
    }
    BigInteger operator % (const BigInteger& b) const {//取模
        BigInteger res = *this - (*this / b) * b;
        return res;
    }
    bool operator < (const BigInteger& b) const {//小于号
        if (len != b.len) return len < b.len;
        for (int i = len; i >= 1; i--) {
            if (num[i] != b.num[i]) {
                return num[i] < b.num[i];
            }
        }
        return false;
    }
    bool operator > (const BigInteger& b) const {//大于号
        return b < *this;
    }
    bool operator == (const BigInteger& b) const {//等于
        return !(b < *this) && !(*this < b);
    }
    bool operator != (const BigInteger& b) const {//不等于
        return b < *this || *this < b;
    }
    bool operator <= (const BigInteger& b) const {//小于等于
        return !(b < *this);
    }
    bool operator >= (const BigInteger& b) const {//大于等于
        return !(*this < b);
    }
};

ostream& operator << (ostream& out, const BigInteger& x) {//输出流
    for (int i = x.len; i >= 1; i--) {
        out << x.num[i];
    }
    return out;
}

istream& operator >> (istream& in, BigInteger& x) {//输入流
    string str;
    in >> str;
    x = BigInteger(str);
    return in;
}

int main() {
    BigInteger a, b, c;
    cin >> a >> b;
    c = a + b;
    cout << c << endl;
    c = a - b;
    cout << c << endl;
    c = a * b;
    cout << c << endl;
    c = a / b;
    cout << c << endl;
    c = a % b;
    cout << c << endl;

    return 0;
}
设计题目

除了编程题目,还有一些设计题目,其中一个题目是要设计一个线上支付系统。该系统要求支持多种支付方式,如支付宝、微信、银联等。同时,还需要考虑支付安全、支付速度、支付手续费等多个方面。我参考了一些已有的线上支付系统,结合自己的经验,最终设计出了一份方案,详见 支付系统设计方案

算法题目

另外还有一道算法题,是要实现一个字符串匹配算法,即在字符串S中找到模式串T的所有出现位置。我使用了KMP算法,时间复杂度O(n+m),其中n为字符串S的长度,m为模式串T的长度。实现代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 100010, M = 100010;

char s[N], p[M];
int ne[M];

int main() {
    cin >> s + 1 >> p + 1;

    int n = strlen(s + 1), m = strlen(p + 1);
    for (int i = 2, j = 0; i <= m; i++) {
        while (j && p[i] != p[j + 1]) j = ne[j];
        if (p[i] == p[j + 1]) j++;
        ne[i] = j;
    }

    for (int i = 1, j = 0; i <= n; i++) {
        while (j && s[i] != p[j + 1]) j = ne[j];
        if (s[i] == p[j + 1]) j++;
        if (j == m) {
            cout << i - m + 1 << ' ';
            j = ne[j];
        }
    }

    return 0;
}

以上是我在亚马逊举办的校内面试中遇到的一些题目和设计问题。在面试过程中,我深感自己的不足,但也乐于接受挑战并不断学习提升。希望这些经验可以对其他程序员有所帮助。