微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

std :: map的行为不正确,如std:unordered_map

如何解决std :: map的行为不正确,如std:unordered_map

我正在尝试解决此问题:https://leetcode.com/problems/3sum/

我的想法是:使用2个哈希表(映射):一个用于负值和零,一个用于正值。

a + b + c = 0-> a + b = -C

因此遍历负值,检查每个正值是否存在负值->那么我们有一个3sum。

我遇到的问题是:

我正在遍历一个映射,该映射具有矢量内数字出现的频率(在threeSum函数中)& 我将数字的频率(number = -1)递减为0: 然后我调用一个函数,该函数应该检查该数字是否存在; 但是它的频率仍然是1! 如果我使用unordered_map,那么就可以使用!

// vector::push_back
#include <iostream>
#include <vector>
#include <map>

using namespace std;


struct CountStruct{
    
    int element1,element2;
    int count1,count2;
};

void keepOriginalCount (map<int,int> &positive_sign,map<int,int> &negative_and_zero_sign,const CountStruct & originalCount)
{
    if (originalCount.element1<0)
    {
        negative_and_zero_sign[originalCount.element1]=originalCount.count1;
    }
    else if (originalCount.element1>0)
    {
        positive_sign[originalCount.element1]=originalCount.count1;
    }
    
    if (originalCount.element2<0)
    {
        negative_and_zero_sign[originalCount.element2]=originalCount.count2;
    }
    else if (originalCount.element2>0)
    {
        positive_sign[originalCount.element2]=originalCount.count2;
    }
        
}

bool findElement (map<int,const int  element,const bool & hasZero)
{
    cout<<"findElement: element="<<element<<endl;
    
    if (element<0)
    {
        if(negative_and_zero_sign[element]>0)
        {
                cout<<"findElement: negative_and_zero_sign[element]="<<negative_and_zero_sign[element]<<endl;

            return true;
        }
        else
        {
            return false;
        }
    }
    else if (element>0)
    {
        if(positive_sign[element]>0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    else 
    {
        if( hasZero == true)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

void fillMaps (map<int,vector<int>& nums,bool & hasZero,int &zeroCount)
{

        for ( unsigned int i =0 ; i< nums.size();i++)
        {
            if(nums[i]<0)
            {
                                cout<<"nums[i]"<<nums[i]<<endl;
                negative_and_zero_sign[nums[i]]++;
            }else if(nums[i]>0){
                cout<<"nums[i]"<<nums[i]<<endl;
                positive_sign[nums[i]]++;
            }
            else
            {
                                cout<<"nums[i]"<<nums[i]<<endl;
                hasZero=true;
                zeroCount++;
            }
        }
}

    vector<vector<int>> threeSum(vector<int>& nums) {
        
            vector<vector<int>> result;
    map<int,int> positive_sign;
    map<int,int> negative_and_zero_sign;
    bool hasZero = false;
    int zeroCount=0;
    
    fillMaps(positive_sign,negative_and_zero_sign,nums,hasZero,zeroCount);
    
    for(auto& itNegative : negative_and_zero_sign) {
    
        
            if (itNegative.second <=0)
            continue;
        
        CountStruct originalCount;
        originalCount.element1 = itNegative.first;
        originalCount.count1 = itNegative.second;
        
        cout<<"---------originalCount.element1 "<<originalCount.element1 <<endl;
        cout<<"---******itNegative.first "<<itNegative.first <<endl;
        cout<<"Before---******itNegative.second "<<itNegative.second <<endl;
        
        itNegative.second--;
        
        cout<<"After---******itNegative.second "<<itNegative.second <<endl;
        
        cout<<"-----------------------------------------------------"<<endl;
        
        for(auto& itPositive : positive_sign) {

            if (itPositive.second <=0)
            continue;
        
            originalCount.element2 = itPositive.first;
            originalCount.count2 = itPositive.second;
        
            cout<<"+++******itPositive.first "<<itPositive.first <<endl;
            cout<<"+++******itPositive.second "<<itPositive.second <<endl;
        
            itPositive.second = itPositive.second - 1;
            
            
            cout<<"+++******After : itPositive.second "<<itPositive.second <<endl;
            
        //  cout<<"--------originalCount.element2 "<<originalCount.element2 <<endl;
            
            if (findElement (positive_sign,(originalCount.element1+originalCount.element2)*-1,hasZero))
            {
                cout<<"Yahoo,element found"<<endl;
                vector <int> temp;
                temp.push_back(originalCount.element1);
                temp.push_back(originalCount.element2);
                temp.push_back( (originalCount.element1+originalCount.element2)*-1);
                result.push_back(temp);
            }
            
            keepOriginalCount(positive_sign,originalCount);
        
        }

        
    }
    
    if(zeroCount >=3)
    {
        vector <int> temp;
        temp.push_back(0);
        temp.push_back(0);
        temp.push_back(0);
        result.push_back(temp);
    }
    
    return result ; 
    }



int main ()
{
vector<int> testV = {1,2,-2,-1};

auto x = threeSum(testV);

  return 0;
}


输出:[[-1,2,-1]] !!应该为空

使用unordered_map

解决方法

您的问题不是由unordered_mapmap引起的。这只是与当前测试向量的随机巧合,以及遍历unordered_map的(原则上)随机顺序。

算法中的真正问题是,您正在还原threeSum方法内循环中所有值的原始计数。

请考虑以下情况:

  • itNegative当前指向元素-1,其频率为1
  • 您将1中的originalElement.count1的频率保持不变,并将itNegative.second--减小,即频率为0
  • 现在内部循环开始运行
    • itPositive指向(例如)元素1,其频率为1
    • 您将1中的originalElement.count2的频率保持不变,并将itPositive.second--减小,即频率为0
    • 您在两张地图中都搜索了0,但是什么也没找到
    • 现在您呼叫keepOriginalCount,它将所有频率重置为其原始值(即-11的频率)
    • 在内部循环的下一次迭代中,itPositive指向2itNegative仍然指向-1
    • 现在您搜索-1(2 + -1) * -1)并找到了它,因为上一步中的keepOriginalCount-1的频率重置为1

解决方案是,不要在内循环中使用keepOriginalCount,而只是重置当前指向的元素itPositive的频率。仅在完成内部循环并且前进到外部循环中的下一个元素之后,才能重置itNegative的频率。您甚至可以完全跳过重设itNegative的频率,因为您已经检查了所有可能的组合,而组合可能是解决方案的一部分。

for(auto& itNegative : negative_and_zero_sign) {
    if (itNegative.second <=0)
        continue;
    
    CountStruct originalCount;
    originalCount.element1 = itNegative.first;
    originalCount.count1 = itNegative.second;
    
    itNegative.second--;  //decrement the frequency of element1
        
    for(auto& itPositive : positive_sign) {
        if (itPositive.second <=0)
            continue;
    
        originalCount.element2 = itPositive.first;
        originalCount.count2 = itPositive.second;
    
        itPositive.second--; //decrement the frequency of element2
        if (findElement (positive_sign,negative_and_zero_sign,(originalCount.element1+originalCount.element2) * -1,hasZero))
        {
            cout<<"Yahoo,element found  " <<  originalCount.element1 << " "<<  originalCount.element2 << endl;
            vector <int> temp;
            temp.push_back(originalCount.element1);
            temp.push_back(originalCount.element2);
            temp.push_back( (originalCount.element1+originalCount.element2) * -1);
            result.push_back(temp);
        }
        itPositive.second++;  //reset only the frequency of element2
    
    }
    itNegative.second++; //reset only the frequency of element1
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。