📌  相关文章
📜  查询以插入,删除数字的一次出现并打印最少和最频繁的元素

📅  最后修改于: 2021-05-30 05:36:59             🧑  作者: Mango

给定Q查询的类型为1、2、3和4,如下所述。

  • 类型1:在列表中插入一个数字。
  • 类型2:仅删除一次出现的数字(如果存在)。
  • 类型3:打印出最不频繁的元素,如果存在多个元素,则打印其中最频繁的元素。
  • Type-4:打印最频繁的元素,如果存在多个元素,则打印其中最小的元素。

任务是编写一个程序来执行上述所有查询。

例子:

天真的方法是使用任何Data-Structures(数组,向量,..)并存储所有元素。使用哈希表,可以存储每个元素的频率。在处理类型2的查询时,请从存储了元素的DS中删除该元素的一次出现。类型3和类型4的查询可以通过遍历哈希表来回答。每个查询的时间复杂度为O(N) ,其中N是DS中直到那时的元素数。

一种有效的方法是使用集合容器来回答每个查询。使用两组,一个哈希表,可以在每个查询的O(log n)中解决上述问题。使用了两组s1s2 ,一组存储{num,frequency} ,而另一组存储{frequency,number} 。使用散列图来存储每个数字的频率。使用运算符重载设计集合s2,以便按第一个元素的升序对它进行排序。如果第一个元素看起来与一个或多个元素相同,则该集合将按第二个元素的降序排序。因此,用户定义的操作重载函数将是:

bool operator b.second;          
 return a.first < b.first;
}
Note: Operator overloading only works with user-defined 
data-types. pr is a struct which has first and second as two integers. 

以下是解决每种类型的查询的算法:

  • Type1:使用哈希表检查元素是否存在。如果不存在,则在哈希表中标记该数字。使用insert()在集合s1中插入{num,1},在集合2中插入{ 1,num} 。如果以前存在,则从哈希表中获取频率,并使用find()和delete()函数从set1中删除{num,frequency} ,并从set2中删除{frequency,num} 。在set1中插入{num,frequency + 1},在set2中插入{ frequency + 1,num} 。另外,增加哈希表中的计数。
  • 类型2:请按照与上述查询类型1相同的过程进行操作。唯一的区别是减少哈希表中的计数,并在set1中插入{num,frequency-1},在set2中插入{frequency-1,num}
  • Type3:打印可以使用begin()函数获得的开始元素,因为该集合的设计方式是使begin()返回最不频繁的元素。如果有多个,则返回最大的。
  • Type4:打印集合中的最后一个元素,可以使用集合中的rbegin()函数获得该元素。

下面是上述方法的实现:

// C++ program for performing 
// Queries of insert, delete one
//  occurrence of a number and 
// print the least and most frequent element
#include 
using namespace std;
  
// user-defined data-types
struct pr {
    int first;
    int second;
};
  
// user-defined function to
// design a set
bool operator<(pr a, pr b)
{
    if (a.first == b.first)
        return a.second > b.second;
    return a.first < b.first;
}
  
// declare a user-defined set
set s1, s2;
  
// hash map 
unordered_map m;
  
// Function to process the query
// of type-1
void type1(int num)
{
  
    // if the element is already there
    if (m[num]) {
  
        // get the frequency of the element
        int cnt = m[num];
  
        // returns an iterator pointing to
        // position where the pair is
        auto it1 = s1.find({ num, cnt });
        auto it2 = s2.find({ cnt, num });
  
        // deletes the pair from sets
        s1.erase(it1);
        s2.erase(it2);
  
        // re-insert the pair by increasing
        // frequency
        s1.insert({ num, m[num] + 1 });
        s2.insert({ m[num] + 1, num });
    }
  
    // if the element is not there in the list
    else {
  
        // insert the element with frequency 1
        s1.insert({ num, 1 });
        s2.insert({ 1, num });
    }
  
    // increase the count in hash-table
    m[num] += 1;
}
  
// Function to process the query
// of type-2
void type2(int num)
{
    // if the element exists
    if (m[num]) {
  
        // get the frequency of the element
        int cnt = m[num];
  
        // returns an iterator pointing to
        // position where the pair is
        auto it1 = s1.find({ num, cnt });
        auto it2 = s2.find({ cnt, num });
  
        // deletes the pair from sets
        s1.erase(it1);
        s2.erase(it2);
  
        // re-insert the pair by increasing
        // frequency
        s1.insert({ num, m[num] - 1 });
        s2.insert({ m[num] - 1, num });
  
        // decrease the count
        m[num] -= 1;
    }
}
  
// Function to process the query
// of type-3
int type3()
{
    // if the set is not empty
    // return the first element
    if (!s1.empty()) {
        auto it = s2.begin();
        return it->second;
    }
  
    else
        return -1;
}
  
// Function to process the query
// of type-4
int type4()
{
  
    // if the set is not empty
    // return the last element
    if (!s1.empty()) {
        auto it = s2.rbegin();
        return it->second;
    }
  
    else
        return -1;
}
// Driver Code
int main()
{
  
    // Queries
  
    // inserts 6, 6 and 7
    type1(6);
    type1(6);
    type1(7);
  
    // print the answer to query of type3
    cout << type3() << endl;
  
    // inserts 7
    type1(7);
  
    // deletes one occurrence of 7
    type2(7);
  
    // inserts 7
    type1(7);
  
    // print the answer to query of type3
    cout << type3() << endl;
  
    // print the answer to query of type4
    cout << type4() << endl;
  
    return 0;
}
输出:
7
7
6

时间复杂度:每个查询O(log N)。
辅助空间: O(N)

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。