Google Interview Question
Software Engineer in Testsif the array is very large, the following would be an improvement:
sort the array, but keep track of each of the elements' original indicies. All 0s will be at the beginning of the sorted array. Find the nth 0 by traversing the sorted array. Once you have that 0, you will have the index in the original array one less than that of the element you want to return. This has a best case complexity of O(logn). Worst case is 0(n) - if all but 1 element is a 0.
We can use switch-case instead of if else to make the code faster.
I don't think we can make the performance better than O(n).
int getNthNonZero(vector<int>& v, const int n)
{
int count = 0;
vector<int> :: iterator i;
for (i = v.begin(); i != v.end(); i++) {
switch (*i) {
case 0:
break;
default:
switch (++count == n) {
case false:
break;
default:
return *i;
}//switch on count
}//switch on *i
}
return ERROR;
}
"We can use switch-case instead of if else to make the code faster."
wtf, how do say that? its just to make the life easier for the programmer and not the way you think. think twice before you post anything.
U fucking cunt.
switch-case is faster than if-else.
http://sequence-points.blogspot.com/2007/10/why-is-switch-statement-faster-than-if.html
So, stop being a ridiculous snob.
A simple optimization would be to start from the end of the array if given n is greater than count/2.
Could not do better than linear complexity, but there are a couple things I would do if it were C programming. Somebody more aware of C++ can be the judge.
+ Pointer deref is always costly w.r.t. cache perf. So, *i should be replaced if possible.
+ use post increment for count i.e. one access only.
+ remove comparison of *i to zero: reduces one cmp instruction
+ register keyword is a possibility: may screw up register optimization by compiler
+ if vector size is known, then compare n and size. If equal, then just check the last one to see if we should even go forward.
+ Test whether vector is empty
how about create another array contains all the non-zeros in the original order. then the rest is simple. Total cost is constructing the array: O(N), then the future cost is O(1)
Whatever you do, you will not gain much improvement with this design. You need to get rid of the search. If your life depends on it, just put the indexes of the zeroes into another vector while you are populating the elements vector; or better, abstract all this away by using a class to manage the data in elements vector.
Do you mean to optimize the algorithm to make the complexity less than O(n)?
- zwfreesky April 10, 2009Also the codes above seems wrong , it should be:
vector<int>::iterator i;
int count;
for (i = elements.begin(); i < elements.end(); i++) {
if ((*i) != 0) {
//count++ should be put here
count++;
if (count == n) {
return (*i);
}
}
}
return -1;
}