给定一个由 n 个整数组成的数组,找到所有对 (i, j) 的 f(a[i], a[j]) 之和,使得 (1 <= i < j <= n)。
f(a[i], a[j]):
If |a[j]-a[i]| > 1
f(a[i], a[j]) = a[j] - a[i]
Else // if |a[j]-a[i]| <= 1
f(a[i], a[j]) = 0
例子:
Input : 6 6 4 4
Output : -8
Explanation:
All pairs are: (6 - 6) + (6 - 6) +
(6 - 6) + (4 - 6) + (4 - 6) + (4 - 6) +
(4 - 6) + (4 - 4) + (4 - 4) = -8
Input: 1 2 3 1 3
Output: 4
Explanation: the pairs that add up are:
(3, 1), (3, 1) to give 4, rest all pairs
according to condition gives 0.
一种幼稚的方法是遍历所有对并计算 f(a[i], a[j]),然后在遍历两个嵌套循环时将其求和将给出我们的答案。
时间复杂度: O(n^2)
一种有效的方法是使用 map/hash函数来记录每个出现的数字,然后遍历列表。在遍历列表时,我们将它前面的数字的数量与数字本身相乘。然后用该数字之前的数字的预和减去该结果,以获得该数字可能的所有对的差值的总和。要删除绝对差 <=1 的所有对,只需从先前计算的总和中减去 (number-1) 和 (number+1) 的出现次数。在这里,我们从计算的总和中减去 (number-1) 的计数,因为它之前已添加到总和中,并且我们添加了 (number+1) 计数,因为负数已添加到所有对的预先计算的总和中.
时间复杂度: O(n)
下面是上述方法的实现:
C++
// CPP program to calculate the
// sum of f(a[i], aj])
#include
using namespace std;
// Function to calculate the sum
int sum(int a[], int n)
{
// map to keep a count of occurrences
unordered_map cnt;
// Traverse in the list from start to end
// number of times a[i] can be in a pair and
// to get the difference we subtract pre_sum.
int ans = 0, pre_sum = 0;
for (int i = 0; i < n; i++) {
ans += (i * a[i]) - pre_sum;
pre_sum += a[i];
// if the (a[i]-1) is present then
// subtract that value as f(a[i], a[i]-1)=0
if (cnt[a[i] - 1])
ans -= cnt[a[i] - 1];
// if the (a[i]+1) is present then
// add that value as f(a[i], a[i]-1)=0
// here we add as a[i]-(a[i]-1)<0 which would
// have been added as negative sum, so we add
// to remove this pair from the sum value
if (cnt[a[i] + 1])
ans += cnt[a[i] + 1];
// keeping a counter for every element
cnt[a[i]]++;
}
return ans;
}
// Driver code
int main()
{
int a[] = { 1, 2, 3, 1, 3 };
int n = sizeof(a) / sizeof(a[0]);
cout << sum(a, n);
return 0;
}
Java
// Java program to calculate
// the sum of f(a[i], aj])
import java.util.*;
public class GfG {
// Function to calculate the sum
public static int sum(int a[], int n)
{
// Map to keep a count of occurrences
Map cnt = new HashMap();
// Traverse in the list from start to end
// number of times a[i] can be in a pair and
// to get the difference we subtract pre_sum
int ans = 0, pre_sum = 0;
for (int i = 0; i < n; i++) {
ans += (i * a[i]) - pre_sum;
pre_sum += a[i];
// If the (a[i]-1) is present then subtract
// that value as f(a[i], a[i]-1) = 0
if (cnt.containsKey(a[i] - 1))
ans -= cnt.get(a[i] - 1);
// If the (a[i]+1) is present then
// add that value as f(a[i], a[i]-1)=0
// here we add as a[i]-(a[i]-1)<0 which would
// have been added as negative sum, so we add
// to remove this pair from the sum value
if (cnt.containsKey(a[i] + 1))
ans += cnt.get(a[i] + 1);
// keeping a counter for every element
if(cnt.containsKey(a[i])) {
cnt.put(a[i], cnt.get(a[i]) + 1);
}
else {
cnt.put(a[i], 1);
}
}
return ans;
}
// Driver code
public static void main(String args[])
{
int a[] = { 1, 2, 3, 1, 3 };
int n = a.length;
System.out.println(sum(a, n));
}
}
// This code is contributed by Swetank Modi
Python3
# Python3 program to calculate the
# sum of f(a[i], aj])
# Function to calculate the sum
def sum(a, n):
# map to keep a count of occurrences
cnt = dict()
# Traverse in the list from start to end
# number of times a[i] can be in a pair and
# to get the difference we subtract pre_sum.
ans = 0
pre_sum = 0
for i in range(n):
ans += (i * a[i]) - pre_sum
pre_sum += a[i]
# if the (a[i]-1) is present then
# subtract that value as f(a[i], a[i]-1)=0
if (a[i] - 1) in cnt:
ans -= cnt[a[i] - 1]
# if the (a[i]+1) is present then add that
# value as f(a[i], a[i]-1)=0 here we add
# as a[i]-(a[i]-1)<0 which would have been
# added as negative sum, so we add to remove
# this pair from the sum value
if (a[i] + 1) in cnt:
ans += cnt[a[i] + 1]
# keeping a counter for every element
if a[i] not in cnt:
cnt[a[i]] = 0
cnt[a[i]] += 1
return ans
# Driver Code
if __name__ == '__main__':
a = [1, 2, 3, 1, 3]
n = len(a)
print(sum(a, n))
# This code is contributed by
# SHUBHAMSINGH10
C#
using System;
using System.Collections.Generic;
// C# program to calculate
// the sum of f(a[i], aj])
public class GfG
{
// Function to calculate the sum
public static int sum(int[] a, int n)
{
// Map to keep a count of occurrences
IDictionary cnt = new Dictionary();
// Traverse in the list from start to end
// number of times a[i] can be in a pair and
// to get the difference we subtract pre_sum
int ans = 0, pre_sum = 0;
for (int i = 0; i < n; i++)
{
ans += (i * a[i]) - pre_sum;
pre_sum += a[i];
// If the (a[i]-1) is present then subtract
// that value as f(a[i], a[i]-1) = 0
if (cnt.ContainsKey(a[i] - 1))
{
ans -= cnt[a[i] - 1];
}
// If the (a[i]+1) is present then
// add that value as f(a[i], a[i]-1)=0
// here we add as a[i]-(a[i]-1)<0 which would
// have been added as negative sum, so we add
// to remove this pair from the sum value
if (cnt.ContainsKey(a[i] + 1))
{
ans += cnt[a[i] + 1];
}
// keeping a counter for every element
if (cnt.ContainsKey(a[i]))
{
cnt[a[i]] = cnt[a[i]] + 1;
}
else
{
cnt[a[i]] = 1;
}
}
return ans;
}
// Driver code
public static void Main(string[] args)
{
int[] a = new int[] {1, 2, 3, 1, 3};
int n = a.Length;
Console.WriteLine(sum(a, n));
}
}
// This code is contributed by Shrikant13
Javascript
输出:
4