📌  相关文章
📜  Q 查询用 K 替换给定索引后 Array 中最频繁的元素

📅  最后修改于: 2021-09-03 02:58:33             🧑  作者: Mango

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

天真的方法:
对于每个查询,将 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)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live