Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 求数组中每对整数的绝对差之和_Algorithm - Fatal编程技术网

Algorithm 求数组中每对整数的绝对差之和

Algorithm 求数组中每对整数的绝对差之和,algorithm,Algorithm,给定一个数组,求每对整数的绝对差之和 例如:给定a[]={2,3,5,7} 输出将是(3-2)+(5-2)+(7-2)+(5-3)+(7-3)+(7-5)=17 它必须比O(n^2)做得更好 原始数组不一定要排序。注意,每个数字加起来正好是k次(如果对列表排序,k是它的位置) 同样,你将每个数字精确地减去n-1-k次 您可以对列表进行排序(O(nlogn)),然后迭代排序后的数组,将每个元素相乘,如上所述 例如:给定一个[]={2,3,5,7} 输出为(3-2)+(5-2)+(7-2)+(5-3

给定一个数组,求每对整数的绝对差之和

例如:给定
a[]={2,3,5,7}

输出将是
(3-2)+(5-2)+(7-2)+(5-3)+(7-3)+(7-5)=17

它必须比
O(n^2)
做得更好


原始数组不一定要排序。

注意,每个数字加起来正好是k次(如果对列表排序,k是它的位置)
同样,你将每个数字精确地减去n-1-k次
您可以对列表进行排序(O(nlogn)),然后迭代排序后的数组,将每个元素相乘,如上所述

例如:给定一个[]={2,3,5,7}
输出为(3-2)+(5-2)+(7-2)+(5-3)+(7-3)+(7-5)=17

我想你可以

  • 用#count-1将每个数字的乘法相加,得到总数
  • 用#count-1对前面开始的每个数字的乘法求和,得到要减去的总数

这将变成
(7*3+5*2+3*1)-(2*3+3*2+5*1)=17
我想我已经找到了答案。我是通过查看我帖子中的结果表达式得到的

这里是C++中的代码.< /P>

intabsdiff(inta[],intn)
{
如果(n<2)返回0;
排序(a,a+n);
整数和=0;
int i;
对于(i=n-1;i>=0;i--)
{
总和+=(a[i]*(i)-a[i]*(n-i-1));
}
回报金额;
}

这只是另一种观点。下面是一个代码:

With[{n = Length@# - 1}, Range[-n, n, 2].Sort[#]] & 
n
=比列表长度小一个

Range[-n,n,2]
2
的步骤创建一个从
-n
n
的数字列表,例如
Range[-4,4,2]
=
{-4,-2,0,2,4}

是向量点积,例如
{a,b,c}。{x,y,z}
=
a x+b y+c z

Sort
就是排序

例如,我们有:
{-3,-1,1,3}。{2,3,5,7}
=
17

下面是列表长度与时间的关系图:


如果数组的大小=4,下面的代码将计算[0](-3)+a[1](-1)+a[2](1)+a[3](3)

result := 0
for i := 0 to sizeof(a)-1 do
begin
   result := result + a[i] * (i*2 - sizeof(a) + 1)
end

如果你需要处理排序数组,你可以先用快速排序算法进行排序,算法的复杂度为O(n*log(n))。

我想我发布这篇文章有点晚了,但我想这个CPP程序应该可以用

//JUST LIKE ANIMALS !!!!

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;

ll funcy(ll a[], ll n)
{

ll sum = 0;
ll i;
for(i=0;i<n;i++)
{
sum += (a[i]*(i) - a[i]*(n-i-1));
}
return sum;
}

int main(){
ios::sync_with_stdio(0);cin.tie(0);
ll i,n;cin>>n;ll v[n+1];
for(i=0;i<n;i++)cin>>v[i];
sort(&v[0],&v[n]);
cout<<AbsDiff(v,n);
return 0;
//就像动物一样!!!!
#包括
使用名称空间std;
typedef long long int ll;
ll funcy(ll a[],ll n)
{
ll sum=0;
我会的;
对于(i=0;i>n;ll v[n+1];
对于(i=0;i>v[i];
排序(&v[0],&v[n]);

JAVA中看一看这段工作代码。 希望它有帮助,有意义

import java.util.Arrays;

public class PairDifference {

    public static void main(String[] args) {
        int[] arr = {2,3,5,7};
        System.out.println(getPairDifference(arr));
    }

    static int getPairDifference(int[] a){
        int diff = 0;
        Arrays.sort(a);
        int n = a.length;
        for(int i=0; i<n; i++)
            diff += (a[i]*i) - (a[n-1-i]*i);

        return diff;
    }

}
导入java.util.array;
公共类对差{
公共静态void main(字符串[]args){
int[]arr={2,3,5,7};
System.out.println(getPairDifference(arr));
}
静态int getPairDifference(int[]a){
int-diff=0;
数组。排序(a);
int n=a.长度;

对于(int i=0;i,首先需要在O(nlogn)时间内对数组进行排序

现在我不会给你这个问题的确切答案,而是给你一个解决这个问题的直觉。 如果我们试图概括指数i上某个特定数字被加和被减的次数,那么对于每个指数i,我们可以使用数学推导的公式来计算绝对差中每个数字在O(N)时间和O(1)额外空间中的贡献之和。

如果您在理解此概念时遇到困难,可以参考此视频


视频链接:-

我知道明显的暴力解决方案。我还认为,连续数字之间的差异将精确显示(n-1)次。但结果与暴力解决方案不匹配。是的,答案基于此。我自己在回答这个问题时也发布了代码。@Gunner-试图解释问题时找到答案的典型案例:).1但我觉得被接受的答案应该是amit。他比我们两个都快。注意,在迭代数组之前需要排序,否则你甚至可能会得到否定的答案。不创建范围列表和点积都是ω(n)?如果我理解正确,排序仍然存在于这两种算法中,并且实际上在大小为n的数组上有2次隐式迭代,而不是1次(点积和创建列表)@amit我想Gunner已经在做我想说明的事情了,但我错过了,因为我不喜欢阅读程序代码。你的观察可能是正确的,但这是在Mathematica中做类似事情的最自然的方式。我的图表显示它的复杂性还不错。@Mr.Wizard:当然不错,它是O(nlogn)用于排序,但如果有,它将比迭代方法更慢,而不是更快。@amit我修改了帖子以纠正这一点。我在发表声明时认为Gunner做的事情效率更低。@Mr.Wizard:毫无疑问,你的选择对于基于数学的语言来说要优雅得多。实际上,你不能用O(n)来做吗使用基数或计数排序,然后按照您提到的方式进行后处理。@Sumod:如果数字的范围有限-是的,您可以使用基数排序/计数排序进行优化。