C++ 第一个唯一编号慢速运行时问题
所以我最近在Leetcode上实现了“第一个唯一编号”。供参考的问题如下: 如果有一个整数队列,则需要检索队列中的第一个唯一整数 实现第一个唯一类:C++ 第一个唯一编号慢速运行时问题,c++,list,stl,queue,unordered-map,C++,List,Stl,Queue,Unordered Map,所以我最近在Leetcode上实现了“第一个唯一编号”。供参考的问题如下: 如果有一个整数队列,则需要检索队列中的第一个唯一整数 实现第一个唯一类: FirstUnique(int[]nums)使用中的数字初始化对象 排队 int showFirstUnique()返回队列的第一个唯一整数的值,如果不存在这样的整数,则返回-1 void add(int value)将值插入队列 使用STL的C++实现使用无序的映射和列表。映射将队列的元素存储为键,并存储指向列表中元素的迭代器和一个布尔值,指
- FirstUnique(int[]nums)使用中的数字初始化对象 排队李>
- int showFirstUnique()返回队列的第一个唯一整数的值,如果不存在这样的整数,则返回-1李>
- void add(int value)将值插入队列
使用STL的C++实现使用无序的映射和列表。映射将队列的元素存储为键,并存储指向列表中元素的迭代器和一个布尔值,指示当值不再唯一时从列表中删除该值。向列表中添加和删除元素似乎是固定时间操作。但是,与另一个使用队列并在队列中迭代的解决方案相比,我的解决方案要慢得多(与我的O(1)相比,它基本上看起来是O(n))
下面是一个显然更糟糕的解决方案:class FirstUnique {
private:
queue<int> q;
unordered_map<int, int> count;
public:
FirstUnique(vector<int>& nums) {
for(int num: nums){
count[num]++;
q.push(num);
}
}
int showFirstUnique() {
while(!q.empty() && count[q.front()] > 1){
q.pop();
}
if(q.empty()){
return -1;
}
else{
return q.front();
}
}
void add(int value) {
if(++count[value] == 1){
q.push(value);
}
}
};
class FirstUnique {
public:
unordered_map<int, pair<list<int>::iterator, bool>> hashmap;
list<int> l;
FirstUnique(vector<int>& nums) {
for(auto it=nums.begin(); it!=nums.end(); it++)
add(*it);
}
int showFirstUnique() {
if (l.empty())
return -1;
return l.back();
}
void add(int value) {
unordered_map<int, pair<list<int>::iterator, bool>>::iterator it = hashmap.find(value);
if(it == hashmap.end())
{
l.push_front(value);
hashmap[value] = make_pair(l.begin(), false) ;
}
else
{
if((it->second).second == false)
{
l.erase((it->second).first);
(it->second).second = true;
}
}
}
};
class-FirstUnique{
私人:
队列q;
无序映射计数;
公众:
FirstUnique(矢量和nums){
for(int-num:nums){
计数[num]++;
q、 推送(num);
}
}
int showFirstUnique(){
而(!q.empty()&&count[q.front()]>1){
q、 pop();
}
if(q.empty()){
返回-1;
}
否则{
返回q.front();
}
}
无效添加(int值){
如果(++计数[值]==1){
q、 推(值);
}
}
};
这是我的解决方案:
class FirstUnique {
private:
queue<int> q;
unordered_map<int, int> count;
public:
FirstUnique(vector<int>& nums) {
for(int num: nums){
count[num]++;
q.push(num);
}
}
int showFirstUnique() {
while(!q.empty() && count[q.front()] > 1){
q.pop();
}
if(q.empty()){
return -1;
}
else{
return q.front();
}
}
void add(int value) {
if(++count[value] == 1){
q.push(value);
}
}
};
class FirstUnique {
public:
unordered_map<int, pair<list<int>::iterator, bool>> hashmap;
list<int> l;
FirstUnique(vector<int>& nums) {
for(auto it=nums.begin(); it!=nums.end(); it++)
add(*it);
}
int showFirstUnique() {
if (l.empty())
return -1;
return l.back();
}
void add(int value) {
unordered_map<int, pair<list<int>::iterator, bool>>::iterator it = hashmap.find(value);
if(it == hashmap.end())
{
l.push_front(value);
hashmap[value] = make_pair(l.begin(), false) ;
}
else
{
if((it->second).second == false)
{
l.erase((it->second).first);
(it->second).second = true;
}
}
}
};
class-FirstUnique{
公众:
无序的_图hashmap;
清单l;
FirstUnique(矢量和nums){
for(auto it=nums.begin();it!=nums.end();it++)
加上(*它);
}
int showFirstUnique(){
if(l.empty())
返回-1;
返回l.back();
}
无效添加(int值){
无序映射::迭代器it=hashmap.find(值);
if(it==hashmap.end())
{
l、 向前推(数值);
hashmap[value]=make_pair(l.begin(),false);
}
其他的
{
if((it->second).second==false)
{
l、 擦除((它->第二个)。第一个);
(it->second)。second=true;
}
}
}
};
我不明白的是,尽管我的解决方案很快,但运行时要慢得多。在Leetcode上,有队列的运行速度为328ms,我的运行速度为532ms。我可以理解我的解决方案内存太大,但无法理解为什么速度较慢。我们只需要将唯一值推送到列表中。要跟踪唯一值,请创建一个无序映射,该映射将跟踪唯一值
public:
list<int> li;
unordered_map<int, bool> m;
FirstUnique(vector<int>& nums) {
for(auto i:nums){
// if i is not in map then we push i to the list an make m[i] = true i.e. unique
// else we make it false. i.e. it is not unique now.
if(m.find(i) == m.end()){
li.push_back(i);
m[i] = true;
}else{
m[i] = false;
}
}
}
int showFirstUnique() {
for(auto it:li){
if(m[it] == true){
return it;
}
}
return -1;
}
void add(int value) {
if(m.find(value) == m.end()){
li.push_back(value);
m[value] = true;
}else{
m[value] = false;
}
}
};
公共:
李名单;
无序地图m;
FirstUnique(矢量和nums){
用于(自动i:nums){
//如果i不在map中,那么我们将i推到列表中,使m[i]=真,即唯一
//否则我们就把它弄错了。也就是说,它现在不是唯一的了。
如果(m.find(i)=m.end()){
li.推回(i);
m[i]=真;
}否则{
m[i]=假;
}
}
}
int showFirstUnique(){
用于(自动it:li){
如果(m[it]==true){
归还它;
}
}
返回-1;
}
无效添加(int值){
如果(m.find(value)=m.end()){
li.推回(值);
m[值]=真;
}否则{
m[值]=假;
}
}
};
我们只需要Java中的LinkedHashMap。它将跟踪收到的物品的订单。在构造函数中,我们将只标记唯一的数字。
在add方法中执行相同的操作。
在showFirstUnique中,我们将遍历映射并返回标记为unique的映射。请参阅下面的代码以了解更多信息
class FirstUnique {
Map<Integer, Integer> map;
public FirstUnique(int[] nums) {
map = new LinkedHashMap<>();
for (int num : nums) {
if (map.containsKey(num)) {
map.put(num, 0);
} else {
map.put(num, 1);
}
}
}
public int showFirstUnique() {
for (Integer key : map.keySet()) {
if (map.get(key) == 1) {
return key;
}
}
return -1;
}
public void add(int value) {
if (map.containsKey(value)) {
map.put(value, 0);
} else {
map.put(value, 1);
}
}
}
class-FirstUnique{
地图;
public FirstUnique(int[]nums){
map=newlinkedhashmap();
for(int-num:nums){
if(映射容器(数量)){
map.put(num,0);
}否则{
map.put(num,1);
}
}
}
public int showFirstUnique(){
for(整数键:map.keySet()){
if(map.get(key)==1){
返回键;
}
}
返回-1;
}
公共void add(int值){
if(映射容器(值)){
map.put(值为0);
}否则{
map.put(值1);
}
}
}
hashmap.find()
在复杂性上是线性的(最坏情况)。此外,常数时间并不总是比O(n)快,它在大多数情况下取决于n(在一个小数组上迭代可能比索引到包含相同数量元素的hashmap要快)。这意味着,如果在定时运行期间使用了add
方法,那么您的解决方案会稍微慢一些也就不足为奇了。