首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阵元与k个阵元之间距离的最小和(绝对差)

阵元与k个阵元之间距离的最小和(绝对差)
EN

Stack Overflow用户
提问于 2021-02-11 13:11:53
回答 1查看 686关注 0票数 0

我需要找到数组中元素与数组中k元素集合之间距离的最小和,不包括该索引。

例如:

arr = {5,7,4,9}

K=2

min_sum(5) =\x{e76f}5-4\x{##**$$}5-7=3

min_sum(7) =_

min_sum(4) =区4-5区+4-7区=4

min_sum(9) =\x{e76f}9-7\x{##**$$}9-5=6

因此,一个简单的解决方案是从数组的每个元素中减去第一个元素,然后对数组进行排序并计算排序数组中前k个元素的和。但太久了..。我相信这是一个dp问题或者类似的问题(可能是脚步声)。

输入:

N-数组元素数

K-集合中的元素数

数组

制约因素:

2 <= n <= 350 000

1 <= k

1 <= ai <= 10^9

时限:2秒

输入:

4.

2

5 7 4 9

输出:

3 4 4 6

解决这个问题最有效的方法是什么?如何优化最小和的搜索?

这是我在C++中的代码,它在n=35万,k=15万的情况下工作约3分钟:

代码语言:javascript
复制
#include <bits/stdc++.h>

using namespace std;

int main() {

    int n, k, tp;
    unsigned long long temp;
    cin >> n >> k;

    vector<unsigned int> org;
    vector<unsigned int> a;
    vector<unsigned long long> cum(n, 0);
    //unordered_map <int, long long> ans;
    unordered_map <int, long long> mp;


    for (int i = 0; i < n; i++){
        cin >> tp;
        org.push_back(tp);
        a.push_back(tp);
    }

/*
    srand(time(0));

    for (int i = 0; i < n; i++){
        org.push_back(rand());
        a.push_back(org[i]);
    }
*/

    sort(a.begin(), a.end());
    partial_sum(a.begin(), a.end(), cum.begin());

    mp[a[0]] = cum[k] - cum[0] - a[0] * k;
    //ans[a[0]] = mp[a[0]];

    for (int i = 1; i <= k; i++) {
       mp[a[i]] = a[i] * i - cum[i-1] + cum[k] - cum[i] - a[i] * (k-i);
    }

    for (int i = 1; i < n-k; i++){
        for (int j = 0; j <= k; j++){
            //if (ans.find(a[i+j]) != ans.end()) {continue;}
            temp = ( (a[i+j] * j) - (cum[i+j-1] - cum[i-1]) ) + ( cum[i+k] - cum[i+j] - a[i+j] * (k-j) );
            if (mp.find(a[i+j]) == mp.end()) { mp[a[i+j]] = temp; }
            else if (mp[a[i+j]] > temp) { mp[a[i+j]] = temp; }
            //else { ans[a[i+j]] = mp[a[i+j]]; }
        }
    }

    for (int i = 0; i < n; i++) {
        cout << mp[org[i]] << " ";
    }

    return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2021-02-11 14:56:20

我觉得这个更好:

首先对数组进行排序,然后您就可以知道这一事实--对于数组中的每个元素i,它与其他元素集的最小距离将是与数组中k个元素周围的元素之间的距离。(当然,它可能在右边,左边,或者两边)。

因此,对于计算min_sum(ai)的每一个元素,都要这样做:

首先,min_sum(ai) = 0。

然后,使用两个索引,将它们标记为r(i的右边)和l(i的左边),并将距离(ai-ar)与距离(ai-al)进行比较。你会把最小的加入到min_sum(ai)中,如果它是右边的,那么增量指数r,如果它是左边的,那么减小指数l。当然,如果左边等于0,右边的是n,你就会从另一边取长度。无论如何,你要这样做,直到你把k个字母相加,仅此而已。

这样,除了主数组之外,您没有对任何东西进行排序。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66155449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档