如何解决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_map
与map
引起的。这只是与当前测试向量的随机巧合,以及遍历unordered_map
的(原则上)随机顺序。
算法中的真正问题是,您正在还原threeSum
方法内循环中所有值的原始计数。
请考虑以下情况:
-
itNegative
当前指向元素-1
,其频率为1
。 - 您将
1
中的originalElement.count1
的频率保持不变,并将itNegative.second--
减小,即频率为0
- 现在内部循环开始运行
-
itPositive
指向(例如)元素1
,其频率为1
- 您将
1
中的originalElement.count2
的频率保持不变,并将itPositive.second--
减小,即频率为0
- 您在两张地图中都搜索了
0
,但是什么也没找到 - 现在您呼叫
keepOriginalCount
,它将所有频率重置为其原始值(即-1
和1
的频率) - 在内部循环的下一次迭代中,
itPositive
指向2
,itNegative
仍然指向-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 举报,一经查实,本站将立刻删除。