大数和中的极值位距离 | 豆包MarsCode AI刷题

76 阅读3分钟

前置知识

高精度加法

思路

模拟手动加法计算即可。

例如计算:567 + 28

先个位相加: 7 + 8 = 15,所以结果的个位是5,向十位进 1

再十位相加: 6 + 2 + 1(进位)= 9, 所以十位是 9,向百位进 0

再百位相加: 5 + 0 = 5, 所以结果的百位是 5

综上,计算结果为 595

算法

计算 567 + 28

用 a, b 两个字符串存储输入。a = 567, b = 28

为了方便计算,将两个数分别 倒序 存放在 A, B 两个整数数组中。 A = [7, 6, 5], B = [8, 2]

新建整数数组 C 保存结果,整型变量 t 保存进位,初始 t = 0.

将各个位上的数字相加,求出结果对应位上的数字和进位。

例如对个位计算: A[0] + B[0] = 7 + 8 = 15, 结果个位上是 5, 进位是 1. 所以 C[0] = 5, 进位 t = 1

最后把结果数组 C 中就保存了计算倒序结果,倒序输出就是答案

本题思路

首先用高精度加法计算出两个大整数的和。

然后我们直接遍历求出最大位和最小位即可,但是需要注意的是题目要求如果有多个最大/最小位我们需要找最近的两个作为答案输出。

这样我们就需要把多个最大/最小位置存下来,然后遍历一下求出位差的最小值。

但这个题目感觉有点抽象,位置 xxyy 的位距离居然是 abs(xy)1abs(x - y) - 1,我感觉有点抽象了,但是最小位置差又是 0。

不过好在题目也说了,如果结果中所有数字都相同,则差距为 0,这样我们最后再和 0 取个 max 就行。

但是这样复杂度其实比较高,假设最大位置和最小位置的数组长度分别为 n,mn,m,那么我们实际上的复杂度为 O(nm)O(nm),可以认为是 O(n2)O(n^2),这样的话 10510^5 的数据是可以轻松卡掉我们的。

实际上最后我们的代码还可以优化一下,就是最后求最小距离的时候可以枚举一个数组的元素,然后二分找到另一个数组中最近的元素,这样可以把复杂度降低到 O(nlogn)O(nlogn),但这题数据比较水,直接暴力枚举就过了。

吐槽:算法题不给数据范围都是耍流氓!

参考代码

vector<int> add(vector<int> &A, vector<int> &B){
    reverse(A.begin(), A.end());
    reverse(B.begin(), B.end());
    vector<int> res;
    int t = 0;
    int i;
    for(i = 0 ; i < max(A.size(), B.size()) ; i ++) {
        if(i < A.size()) t += A[i];
        if(i < B.size()) t += B[i];
        res.push_back(t % 10);
        t /= 10;
    }
    if(t) res.push_back(t % 10);
    reverse(res.begin(), res.end());
    return res;
}

int solution(std::string a, std::string b) {
    // Please write your code here
    vector<int> A, B;
    for(int i = 0 ; i < a.size() ; i ++)    A.push_back(a[i] - '0');
    for(int i = 0 ; i < b.size() ; i ++)    B.push_back(b[i] - '0');
    auto C = add(A, B); 
    // for(auto x : C)
    //     cout << x;
    // cout << endl;
    int maxv = -1, minv = 10;
    vector<int> mxp, mip;
    for(int i = 0 ; i < C.size() ; i ++) {
        int x = C[i];
        if(maxv < x) {
            maxv = x;
            mxp.clear();
            mxp.push_back(i);
        } else if(maxv == x) mxp.push_back(i);

        if(minv > x) {
            minv = x;
            mip.clear();
            mip.push_back(i);
        } else if(minv == x) mip.push_back(i);
    }   
    int ans = 1e9;
    for(auto x : mxp)
        for(auto y : mip)
            ans = min(ans, max(0, abs(x - y) - 1));
    // cout << ans << endl;
    return ans;
}