//blame: shardy@@differentchairs.com
#include <stdio.h>
#include <map>
//
// find a value in the given list that occurs an odd number of times
//
// (return defVal if no match found)
//
int findOddCount(int *val, int valSize, int defVal=-1)
{
using namespace std;
map<int,int> bucket;
for (int i=0; i<valSize; i++) {
bucket[val[i]]++;
}
for (map<int,int>::iterator ii=bucket.begin();ii!=bucket.end();++ii) {
if ((*ii).second % 2) {
return (*ii).first;
}
}
return defVal;
}
//
// another approach... (sort, then scan)
// O(nlogn + n)
//
int findOddCount2(int *val, int valSize, int defVal=-1)
{
std::vector<int> v(val, val+valSize);
std::sort(v.begin(), v.end());
int valct = 0;
int oldval = 0;
for (size_t i=0; i<v.size(); ++i) {
if (v[i] != oldval) {
if (valct%2)
return oldval;
oldval=v[i];
valct=1;
}
else
valct++;
}
return defVal;
}
//
// this approach (sort, then bsearch) presumes no more than one oddCount.
// O(nlogn) for the sort, then O(logn) to find the value
//
int findOddCount3(int *val, int valSize, int defVal=-1)
{
std::vector<int> v(val, val+valSize);
std::sort(v.begin(), v.end());
int valct = 0;
int oldval = 0;
int lwr=0;
int upr=valSize;
// find last boundary between values that's on even index
while (lwr<upr) {
int mid = lwr + (upr-lwr)/2;
int thisval=v[mid];
int beg;
for (beg=mid-1; beg>=0 && v[beg]==thisval; --beg)
;
if (beg>0 && !beg%2)
upr = beg+1;
else {
int end;
for (end=mid+1; end<upr && v[end]==thisval; ++end)
;
if (end%2)
return thisval;
lwr = end;
}
}
return defVal;
}
int main(int /*argc*/, char* /*argv*/[])
{
int a1[]= {1,1,2,2,3,3,4,4,5,5,6,7,7,7,7};
int a2[]= {10,10,7,7,6,6, 2,2,3,3,4,4,5,5,6,7,7,7,7,10,10};
int a3[]= {6,6,10,10,7,7,6,6, 2,2,3,3,4,4,5,5,6,7,7,7,7,10,10};
int a4[]= {10,10,7,7, 2,2,3,3,4,4,5,5,7,7,7,7,10,10,6};
int a5[]= {6,6};
int a6[]= {1};
printf("odd value in a1 is %d\n",
findOddCount(a1,sizeof(a1)/sizeof(*a1) ));
printf("odd value in a2 is %d\n",
findOddCount(a2,sizeof(a2)/sizeof(*a2) ));
printf("odd value in a3 is %d\n",
findOddCount(a3,sizeof(a3)/sizeof(*a3) ));
printf("odd value in a4 is %d\n",
findOddCount(a4,sizeof(a4)/sizeof(*a4) ));
printf("odd value in a5 is %d\n",
findOddCount(a5,sizeof(a5)/sizeof(*a5) ));
printf("odd value in a6 is %d\n",
findOddCount(a6,sizeof(a6)/sizeof(*a6) ));
return 0;
}