给定一个由N 个整数组成的数组arr[] ,每个数组元素arr[i]的任务是打印|i – j| 的和对于所有可能的索引j使得arr[i] = arr[j] 。
例子:
Input: arr[] = {1, 3, 1, 1, 2}
Output: 5 0 3 4 0
Explanation:
For arr[0], sum = |0 – 0| + |0 – 2| + |0 – 3| = 5.
For arr[1], sum = |1 – 1| = 0.
For arr[2], sum = |2 – 0| + |2 – 2| + |2 – 3| = 3.
For arr[3], sum = |3 – 0| + |3 – 2| + |3 – 3| = 4.
For arr[4], sum = |4 – 4| = 0.
Therefore, the required output is 5 0 3 4 0.
Input: arr[] = {1, 1, 1}
Output: 3 2 3
朴素的方法:请参阅本文的前一篇文章,了解解决问题的最简单方法。
时间复杂度: O(N 2 )
辅助空间: O(N)
Map- based Approach:使用Map解决问题请参考本文前一篇。
时间复杂度: O(N*L)
辅助空间: O(N)
高效的方法:上述方法也可以通过在 HashMap 中存储前一个索引和每个元素的出现次数来优化。请按照以下步骤解决问题:
- 初始化一个 HashMap,假设M将arr[i]存储为键,并将(count, previous index) 存储为值。
- 初始化两个大小为N 的数组L[]和R[] ,其中L[i]表示|i – j|的总和对于所有可能的索引j < i和arr[i] = arr[j]和R[i]表示|i – j|的总和对于所有可能的索引j > i和arr[i] = arr[j] 。
- 在[0, N – 1]范围内遍历给定数组arr[ ]并执行以下步骤:
- 如果arr[i]存在于映射M 中,则将L[i]的值更新为0和M[arr[i]]以存储对{1, i} ,其中第一个元素表示出现次数,而第二个元素表示元素的前一个索引。
- 否则,从映射M 中找到arr[i]的值,并将计数和上一个索引分别存储在变量cnt和j 中。
- 将L[i]的值更新为(cnt * (i – j) + L[j])和M中arr[i]的值以存储对(cnt + 1, i) 。
- 重复相同的过程以更新数组R[] 中的值。
- 使用变量i在范围[0, N – 1] 上迭代并打印值(L[i] + R[i])作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Stores the count of occurrences
// and previous index of every element
struct pairr
{
int count, prevIndex;
// Constructor
pairr(int countt, int prevIndexx)
{
count = countt;
prevIndex = prevIndexx;
}
};
// Function to calculate the sum of
// absolute differences of indices
// of occurrences of array element
void findSum(int arr[], int n)
{
// Stores the count of elements
// and their previous indices
map mapp;
// Initialize 2 arrays left[]
// and right[] of size N
int left[n];
int right[n];
// Traverse the given array
for(int i = 0; i < n; i++)
{
// If arr[i] is present in the Map
if (mapp.find(arr[i]) == mapp.end())
{
// Update left[i] to 0
// and update the value
// of arr[i] in map
left[i] = 0;
mapp[arr[i]] = new pairr(1, i);
}
// Otherwise, get the value from
// the map and update left[i]
else
{
pairr* tmp = mapp[arr[i]];
left[i] = (tmp->count) * (i - tmp->prevIndex) +
left[tmp->prevIndex];
mapp[arr[i]] = new pairr(tmp->count + 1, i);
}
}
// Clear the map to calculate right[] array
mapp.clear();
// Traverse the array arr[] in reverse
for(int i = n - 1; i >= 0; i--)
{
// If arr[i] is present in theMap
if (mapp.find(arr[i]) == mapp.end())
{
// Update right[i] to 0
// and update the value
// of arr[i] in the Map
right[i] = 0;
mapp[arr[i]] = new pairr(1, i);
}
// Otherwise get the value from
// the map and update right[i]
else
{
pairr* tmp = mapp[arr[i]];
right[i] = (tmp->count) *
(abs(i - tmp->prevIndex)) +
right[tmp->prevIndex];
mapp[arr[i]] = new pairr(tmp->count + 1, i);
}
}
// Iterate in the range [0, N-1]
// and print the sum of left[i]
// and right[i] as the result
for(int i = 0; i < n; i++)
cout << left[i] + right[i] << " ";
}
// Driver Code
int main()
{
int arr[] = { 1, 3, 1, 1, 2 };
int N = 5;
findSum(arr, N);
}
// This code is contributed by mohit kumar 29
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Stores the count of occurrences
// and previous index of every element
static class pair {
int count, prevIndex;
// Constructor
pair(int count, int prevIndex)
{
this.count = count;
this.prevIndex = prevIndex;
}
}
// Function to calculate the sum of
// absolute differences of indices
// of occurrences of array element
static void findSum(int[] arr, int n)
{
// Stores the count of elements
// and their previous indices
Map map = new HashMap<>();
// Initialize 2 arrays left[]
// and right[] of size N
int[] left = new int[n];
int[] right = new int[n];
// Traverse the given array
for (int i = 0; i < n; i++) {
// If arr[i] is present in the Map
if (!map.containsKey(arr[i])) {
// Update left[i] to 0
// and update the value
// of arr[i] in map
left[i] = 0;
map.put(arr[i], new pair(1, i));
}
// Otherwise, get the value from
// the map and update left[i]
else {
pair tmp = map.get(arr[i]);
left[i] = (tmp.count)
* (i - tmp.prevIndex)
+ left[tmp.prevIndex];
map.put(
arr[i], new pair(
tmp.count + 1, i));
}
}
// Clear the map to calculate right[] array
map.clear();
// Traverse the array arr[] in reverse
for (int i = n - 1; i >= 0; i--) {
// If arr[i] is present in theMap
if (!map.containsKey(arr[i])) {
// Update right[i] to 0
// and update the value
// of arr[i] in the Map
right[i] = 0;
map.put(arr[i], new pair(1, i));
}
// Otherwise get the value from
// the map and update right[i]
else {
pair tmp = map.get(arr[i]);
right[i]
= (tmp.count)
* (Math.abs(i - tmp.prevIndex))
+ right[tmp.prevIndex];
map.put(
arr[i], new pair(
tmp.count + 1, i));
}
}
// Iterate in the range [0, N-1]
// and print the sum of left[i]
// and right[i] as the result
for (int i = 0; i < n; i++)
System.out.print(
left[i] + right[i] + " ");
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 1, 3, 1, 1, 2 };
int N = arr.length;
findSum(arr, N);
}
}
5 0 3 4 0
时间复杂度: O(N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live