📌  相关文章
📜  每个数组元素的出现索引的绝对差之和|套装2

📅  最后修改于: 2021-04-22 08:44:41             🧑  作者: Mango

给定一个由N个整数组成的数组arr [] ,每个数组元素arr [i]的任务是打印| i – j |的和。对于所有可能的索引j ,使得arr [i] = arr [j]

例子:

天真的方法:请参阅本文的上一篇文章,以解决问题的最简单方法。
时间复杂度: O(N 2 )
辅助空间: O(N)

基于地图的方法:请参考本文的上一篇文章,以解决使用地图的问题。
时间复杂度: O(N * L)
辅助空间: O(N)

高效方法:还可以通过在HashMap中存储先前的索引和每个元素的出现次数来优化上述方法。请按照以下步骤解决问题:

  • 初始化一个HashMap,说M来存储arr [i]作为键和(count,前一个索引)作为值。
  • 初始化大小为N的两个数组L []R [] ,其中L [i]表示| i – j |的和。对于所有可能的索引j arr [i] = arr [j]R [i]表示| i – j |的和。对于所有可能的索引j> iarr [i] = arr [j]
  • [0,N – 1]范围内遍历给定数组arr [ ]并执行以下步骤:
    • 如果在映射M中存在arr [i] ,则将L [i]的值更新为0 ,将M [arr [i]]的值更新为存储对{1,i} ,其中第一个元素表示出现次数,第二个元素表示该元素的上一个索引。
    • 否则,从映射M中找到arr [i]的值,并将计数和先前索引分别存储在变量cntj中
    • L [i]的值更新为(cnt *(i – j)+ L [j])M中arr [i]的值以存储对(cnt + 1,i)
  • 重复相同的过程以更新数组R []中的值。
  • 使用变量i[0,N – 1]范围内进行迭代并打印结果(L [i] + R [i])

下面是上述方法的实现:

Java
// Java program for the above approach
  
import java.util.*;
  
class GFG {
  
    // Stores the count of occurrences
    // and the 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 element
        // and its previous index
        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));
            }
  
            // Else 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 order
        for (int i = n - 1; i >= 0; i--) {
  
            // If arr[i] is present in
            // the map
            if (!map.containsKey(arr[i])) {
  
                // Update right[i] to 0
                // and update the value
                // of arr[i] in 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)