📌  相关文章
📜  将Q的给定索引替换为K后,Array中最频繁的元素

📅  最后修改于: 2021-05-17 06:34:17             🧑  作者: Mango

给定大小为N的数组arr [] ,并使用{i,k}形式的Q查询,任务是在用k替换arr [i]之后打印数组中最频繁出现的元素
例子 :

天真的方法:
对于每个查询,将arr [i]替换为K,遍历整个数组并计算每个数组元素的频率,并打印最频繁的元素。
时间复杂度: O(N * Q)
辅助空间: O(N)
高效方法:
可以通过预先计算每个数组元素的频率并将频率数组元素配对保持在一组中以获得O(1)中最频繁的元素来优化上述方法。请按照以下步骤解决问题:

  1. 初始化映射以存储所有阵列元素的频率,并初始化一组对以存储频率元素对。在集合中,将频率存储为负数。这确保了存储在集合开始处的第一对iesbegin()是{-(最大频率),最频繁元素}配对。
  2. 对于每个查询,在删除第i索引处的数组元素的同时,请执行以下任务:
    • 从映射图中找到arr [i]的频率,即mp [arr [i]]。
    • 从集合中删除对{-mp [arr [i]],arr [i]}
    • 通过在集合中插入{-(mp [arr [i] – 1),arr [i]}),在降低arr [i]的频率后更新集合。
    • 降低图中arr [i]的频率。
    • 要将每个查询的K插入数组,请执行以下操作:
      • 从图中找到K的频率,即mp [K]
      • 从集合中删除对{-mp [K],K}
      • 通过将{-(mp [K] + 1),K}插入集合来增加K的频率后更新集合。
      • 增加地图中K的频率。
    • 最后,对于每个查询,在集合的开头提取对。集合中的第一个元素表示-(最大频率) 。因此,第二个元素将是最常见的元素。打印该对的第二个元素。

下面是上述方法的实现:

C++
// C++ program to find the most
// frequent element after every
// update query on the array
 
#include 
using namespace std;
 
typedef long long int ll;
 
// Function to print the most
// frequent element of array
// along with update querry
void mostFrequent(ll arr[], ll n, ll m,
                vector > q)
{
    ll i;
 
    // Stores element->fequencies
    // mappings
    map mp;
 
    for (i = 0; i < n; i++)
        mp[arr[i]] += 1;
 
    // Stores frequencies->element
    // mappings
    set > s;
 
    // Store the frequencies in
    // negative
    for (auto it : mp) {
        s.insert(make_pair(-(it.second),
                        it.first));
    }
 
    for (i = 0; i < m; i++) {
 
        // Index to be modified
        ll j = q[i][0];
 
        // Value to be inserted
        ll k = q[i][1];
 
        // Store the frequency of
        // arr[j] and k
        auto it = mp.find(arr[j]);
        auto it2 = mp.find(k);
 
        // Remove mapping of arr[j]
        // with previous frequency
        s.erase(make_pair(-(it->second),
                        it->first));
 
        // Update mapping with new
        // frequency
        s.insert(make_pair(-((it->second)
                            - 1),
                        it->first));
 
        // Update frequency of arr[j]
        // in the map
        mp[arr[j]]--;
 
        // Remove mapping of k
        // with previous frequency
        s.erase(make_pair(-(it2->second),
                        it2->first));
 
        // Update mapping of k
        // with previous frequency
        s.insert(make_pair(-((it2->second)
                            + 1),
                        it2->first));
 
        // Update frequency of k
        mp[k]++;
 
        // Replace arr[j] by k
        arr[j] = k;
 
        // Display maximum frequent element
        cout << (*s.begin()).second << " ";
    }
}
// Driver Code
int main()
{
 
    ll i, N, Q;
    N = 5;
    Q = 3;
    ll arr[] = { 2, 2, 2, 3, 3 };
    vector > querry = {
        { 0, 3 },
        { 4, 2 },
        { 0, 4 }
    };
 
    mostFrequent(arr, N, Q, querry);
}


Java
// Java program to find the most
// frequent element after every
// update query on the array
import java.util.*;
import java.io.*;
 
class GFG{
     
// Pair class represents
// a pair of elements
static class Pair
{
    int first, second;
    Pair(int f,int s)
    {
        first = f;
        second = s;
    }
}
 
// Function to print the most
// frequent element of array
// along with update querry
static void mostFrequent(int arr[], int n, int m,
                         ArrayList q)
{
    int i;
 
    // Stores element->fequencies
    // mappings
    HashMap map = new HashMap<>();
    HashMap map1 = new HashMap<>();
     
    for(i = 0; i < n; i++)
    {
        if(!map.containsKey(arr[i]))
            map.put(arr[i], 1);
        else
            map.put(arr[i], map.get(arr[i]) + 1);
    }
 
    // Stores frequencies->element
    // mappings
    TreeSet set = new TreeSet<>(
                        new Comparator()
    {
        public int compare(Pair p1, Pair p2)
        {
            return p2.first - p1.first;
        }
    });
 
    // Store the frequencies in
    // bigger to smaller
    for(Map.Entry entry : map.entrySet())
    {
        Pair p = new Pair(entry.getValue(),
                          entry.getKey());
        set.add(p);
        map1.put(entry.getKey(), p);
    }
 
    for(i = 0; i < m; i++)
    {
         
        // Index to be modified
        int j = q.get(i).first;
 
        // Value to be inserted
        int k = q.get(i).second;
         
        // Insert the new Pair
        // with value k if it was
        // not inserted
        if(map1.get(k) == null)
        {
            Pair p = new Pair(0, k);
            map1.put(k, p);
            set.add(p);
        }
         
        // Get the Pairs of
        // arr[j] and k
        Pair p1 = map1.get(arr[j]);
        set.remove(p1);
        Pair p2 = map1.get(k);
        set.remove(p2);
         
        // Decrease the frequency of
        // mapping with value arr[j]
        p1.first--;
        set.add(p1);
 
        // Update frequency of arr[j]
        // in the map
        map.put(arr[j], map.get(arr[j]) - 1);
 
        // Increase the frequency of
        // mapping with value k
        p2.first++;
        set.add(p2);
         
        // Update frequency of k
        if(map.containsKey(k))
            map.put(k, map.get(k) + 1);
        else
            map.put(k, 1);
 
        // Replace arr[j] by k
        arr[j] = k;
 
        // Display maximum frequent element
        System.out.print(
            set.iterator().next().second + " ");
    }
}
 
// Driver Code
public static void main(String []args)
{
    int i, N, Q;
    N = 5;
    Q = 3;
    int arr[] = { 2, 2, 2, 3, 3 };
     
    ArrayList query = new ArrayList<>();
    query.add(new Pair(0, 3));
    query.add(new Pair(4, 2));
    query.add(new Pair(0, 4));
     
    mostFrequent(arr, N, Q, query);
}
}
 
// This code is contributed by Ganeshchowdharysadanala


Python3
# Python program to find the most
# frequent element after every
# update query on the array
from typing import List
from collections import defaultdict
 
# Function to print the most
# frequent element of array
# along with update querry
def mostFrequent(arr: List[int], n: int, m: int, q: List[List[int]]) -> None:
    i = 0
 
    # Stores element->fequencies
    # mappings
    mp = defaultdict(lambda: 0)
    for i in range(n):
        mp[arr[i]] += 1
 
    # Stores frequencies->element
    # mappings
    s = set()
 
    # Store the frequencies in
    # negative
    for k, v in mp.items():
        s.add((-v, k))
    for i in range(m):
 
        # Index to be modified
        j = q[i][0]
 
        # Value to be inserted
        k = q[i][1]
 
        # Store the frequency of
        # arr[j] and k
        it = mp[arr[j]]
        it2 = mp[k]
 
        # Remove mapping of arr[j]
        # with previous frequency
        if (-it, arr[j]) in s:
            s.remove((-it, arr[j]))
 
        # Update mapping with new
        # frequency
        s.add((-(it - 1), arr[j]))
 
        # Update frequency of arr[j]
        # in the map
        mp[arr[j]] -= 1
 
        # Remove mapping of k
        # with previous frequency
        if (-it2, k) in s:
            s.remove((-it2, k))
 
        # Update mapping of k
        # with previous frequency
        s.add((-(it2 + 1), k))
 
        # Update frequency of k
        mp[k] += 1
 
        # Replace arr[j] by k
        arr[j] = k
 
        # Display maximum frequent element
        print(sorted(s)[0][1])
 
# Driver Code
if __name__ == "__main__":
 
    N = 5
    Q = 3
    arr = [2, 2, 2, 3, 3]
    querry = [[0, 3], [4, 2], [0, 4]]
    mostFrequent(arr, N, Q, querry)
 
# This code is contributed by sanjeev2552


输出:

3 2 2 

时间复杂度: O(N +(Q * LogN))
辅助空间: O(N)