问题:
给定数组,是否从数组中选取元素,两两有二倍关系,刚好分配完所有的元素。
Example 1: Input: [3,1,3,6] Output: false Example 2: Input: [2,1,2,6] Output: false Example 3: Input: [4,-2,2,-4] Output: true Explanation: We can take two groups, [-2,-4] and [2,4] to form [-2,-4,2,4] or [2,4,-2,-4]. Example 4: Input: [1,2,4,16,8,4] Output: false Note: 0 <= A.length <= 30000 A.length is even -100000 <= A[i] <= 100000
解法1:
构建默认key排序的map,
key为元素值,value为元素个数
记录此时map的size,遍历map,
对每一值coutA(cout!=0),去找paira=2*a是否存在与map中。
存在的话,且cout!=0
那么两两的cout值抵消。(都剪去更小的那个值)
若此时cout==0,那么map的size--;
到最后如果size==0,那么返回true。否则返回false。
⚠️特别的,对于元素值0,其二倍paira仍为0,则做特殊处理,
若其cout数为2的倍数,那么size--,继续检查其他元素,否则返回false。
代码参考:
1 class Solution { 2 public: 3 bool canReorderDoubled(vector<int>& A) { 4 map<int, int> Amap; 5 int size=0; 6 for(int a:A){ 7 Amap[a]++; 8 } 9 size=Amap.size(); 10 for(auto coutA=Amap.begin(); coutA!=Amap.end(); coutA++){ 11 if(coutA->second==0) continue; 12 if(coutA->first==0){ 13 if(coutA->second%2!=0) return false; 14 coutA->second==0; 15 size--; 16 continue; 17 } 18 auto paira = Amap.find(coutA->first*2); 19 if(paira!=Amap.end() && paira->second!=0){ 20 int minvalue=min(coutA->second, paira->second); 21 paira->second-=minvalue; 22 coutA->second-=minvalue; 23 if(paira->second==0) size--; 24 if(coutA->second==0) size--; 25 } 26 } 27 return size==0; 28 } 29 };
解法2:
代替1中的排序map,我们使用一个unordered_map和一个vector进行排序来做
unordered_map同map记录数组元素及其计数。
然后将map的所有key,拿出来,push到vector中,
并对vector进行【绝对值排序】得到sortkey
(为了使得遍历vector时,a 在 2*a 之前)
1 sort(sortkey.begin(), sortkey.end(), [](int a, int b){return abs(a) < abs(b);});
然后遍历sortkey
若 k 的cout(通过key可以简单在unordered_map中找其计数cout > k*2 的cout,
那么之后将不可能出现来抵消 k 的元素,所以返回false。
其他的将 k*2 的cout抵消掉 k 的cout,Cout[k*2]-=Cout[k]
若之后k*2再也找不到抵消其cout的元素(k*2*2),
那么 也就是说,Cout[k*2] > Cout[k*2*2],则在上面的判断中已经返回false。
代码参考:
1 class Solution { 2 public: 3 bool canReorderDoubled(vector<int>& A) { 4 unordered_map<int, int> Amap; 5 vector<int> sortkey; 6 for(int a:A){ 7 Amap[a]++; 8 } 9 for(auto a:Amap){ 10 sortkey.push_back(a.first); 11 } 12 sort(sortkey.begin(), sortkey.end(), [](int a, int b){return abs(a) < abs(b);}); 13 14 for(auto k:sortkey){ 15 if(Amap[k]>Amap[k*2]) return false; 16 Amap[k*2]-=Amap[k]; 17 } 18 return true; 19 } 20 };