给定一个由N 个整数组成的数组 arr[]和一个数字K ,任务是找到给定数组中所有对的 K 次幂的绝对差之和,即, .
例子:
Input: arr[] = {1, 2, 3}, K = 1
Output: 8
Explanation:
Sum of |1-1|+|1-2|+|1-3|+|2-1|+|2-2|+|2-3|+|3-1|+|3-2|+|3-3| = 8
Input: arr[] = {1, 2, 3}, K = 3
Output: 20
Explanation:
Sum of |1 – 1| 3 + |1 – 2| 3 + |1 – 3| 3 + |2 – 1| 3 + |2 – 2| 3 + |2 – 3| 3 + |3 – 1| 3 + |3 – 2| 3 + |3 – 3| 3 = 20
朴素方法:这个想法是生成所有可能的对,并找到每对的绝对差值的K 次幂,然后将它们相加。
时间复杂度: O((log K)*N 2 )
辅助空间: O(1)
高效方法:我们可以通过以下计算来提高朴素方法的时间复杂度:
对于所有可能的对,我们必须找到
由于对 (arr[i], arr[j]) 的值被计算两次。所以上面的方程也可以写成:
写作在二项式方程方面:
(Equation 1)
让 Pre[i][a] = (公式 2)
从方程 1 和方程 2,我们有
Pre[i][a] 的值可以计算为:
Pre[i][a] = {(-arr[1])K – a + (-arr[2])K – a … . . +(-arr[i – 1])K – a}.
So, Pre[i+1][a] = Pre[i][a]+(-arr[i])K – a
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
#define ll long long
using namespace std;
class Solution {
public:
// Since K can be 100 max
ll ncr[101][101];
int n, k;
vector A;
// Constructor
Solution(int N, int K, vector B)
{
// Initializing with -1
memset(ncr, -1, sizeof(ncr));
n = N;
k = K;
A = B;
// Making vector A as 1-Indexing
A.insert(A.begin(), 0);
}
ll f(int N, int K);
ll pairsPower();
};
// To Calulate the value nCk
ll Solution::f(int n, int k)
{
if (k == 0)
return 1LL;
if (n == k)
return 1LL;
if (n < k)
return 0;
if (ncr[n][k] != -1)
return ncr[n][k];
// Since nCj = (n-1)Cj + (n-1)C(j-1);
return ncr[n][k] = f(n - 1, k)
+ f(n - 1, k - 1);
}
// Function that summation of absolute
// differences of all pairs raised
// to the power k
ll Solution::pairsPower()
{
ll pre[n + 1][k + 1];
ll ans = 0;
// Sort the given array
sort(A.begin() + 1, A.end());
// Precomputation part, O(n*k)
for (int i = 1; i <= n; ++i) {
pre[i][0] = 1LL;
for (int j = 1; j <= k; j++) {
pre[i][j] = A[i]
* pre[i][j - 1];
}
if (i != 1) {
for (int j = 0; j <= k; ++j)
pre[i][j] = pre[i][j]
+ pre[i - 1][j];
}
}
// Traverse the array arr[]
for (int i = n; i >= 2; --i) {
// For each K
for (int j = 0; j <= k; j++) {
ll val = f(k, j);
ll val1 = pow(A[i], k - j)
* pre[i - 1][j];
val = val * val1;
if (j % 2 == 0)
ans = (ans + val);
else
ans = (ans - val);
}
}
ans = 2LL * ans;
// Return the final answer
return ans;
}
// Driver Code
int main()
{
// Given N and K
int N = 3;
int K = 3;
// Given array
vector arr = { 1, 2, 3 };
// Creation of Object of class
Solution obj(N, K, arr);
// Function Call
cout << obj.pairsPower() << endl;
return 0;
}
Python3
# Python3 program for the above approach
class Solution:
def __init__(self, N, K, B):
self.ncr = []
# Since K can be 100 max
for i in range(101):
temp = []
for j in range(101):
# Initializing with -1
temp.append(-1)
self.ncr.append(temp)
self.n = N
self.k = K
# Making vector A as 1-Indexing
self.A = [0] + B
# To Calulate the value nCk
def f(self, n, k):
if k == 0:
return 1
if n == k:
return 1
if n < k:
return 0
if self.ncr[n][k] != -1:
return self.ncr[n][k]
# Since nCj = (n-1)Cj + (n-1)C(j-1);
self.ncr[n][k] = (self.f(n - 1, k) +
self.f(n - 1, k - 1))
return self.ncr[n][k]
# Function that summation of absolute
# differences of all pairs raised
# to the power k
def pairsPower(self):
pre = []
for i in range(self.n + 1):
temp = []
for j in range(self.k + 1):
temp.append(0)
pre.append(temp)
ans = 0
# Sort the given array
self.A.sort()
# Precomputation part, O(n*k)
for i in range(1, self.n + 1):
pre[i][0] = 1
for j in range(1, self.k + 1):
pre[i][j] = (self.A[i] *
pre[i][j - 1])
if i != 1:
for j in range(self.k + 1):
pre[i][j] = (pre[i][j] +
pre[i - 1][j])
# Traverse the array arr[]
for i in range(self.n, 1, -1):
# For each K
for j in range(self.k + 1):
val = self.f(self.k, j)
val1 = (pow(self.A[i],
self.k - j) *
pre[i - 1][j])
val = val * val1
if j % 2 == 0:
ans = ans + val
else:
ans = ans - val
ans = 2 * ans
# Return the final answer
return ans
# Driver code
if __name__ == '__main__':
# Given N and K
N = 3
K = 3
# Given array
arr = [ 1, 2, 3 ]
# Creation of object of class
obj = Solution(N, K, arr)
# Function call
print(obj.pairsPower())
# This code is contributed by Shivam Singh
20
时间复杂度: O(N*K)
辅助空间: O(N*K)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live