Reputation: 401
I had an interview for a Jr. development job and he asked me to write a procedure that takes an array of ints and shoves the zeroes to the back. Here are the constraints (which he didn't tell me at the beginning .... As often happens in programming interviews, I learned the constraints of the problem while I solved it lol):
Setup:
int arr[] = {0, -2, 4, 0, 19, 69};
/* Transform arr to {-2, 4, 19, 69, 0, 0} or {69, 4, -2, 19, 0, 0}
or anything that pushes all the nonzeros to the back and keeps
all the nonzeros in front */
My answer:
bool f (int a, int b) {return a == 0;}
std::sort(arr, arr+sizeof(arr)/sizeof(int), f);
What are some other good answers?
Upvotes: 6
Views: 483
Reputation: 35454
Maybe the interviewer was looking for this answer:
#include <algorithm>
//...
std::partition(std::begin(arr), std::end(arr), [](int n) { return n != 0; });
If the order needs to be preserved, then std::stable_partition
should be used:
#include <algorithm>
//...
std::stable_partition(std::begin(arr), std::end(arr), [](int n) { return n != 0; });
For pre C++11:
#include <functional>
#include <algorithm>
//...
std::partition(arr, arr + sizeof(arr)/sizeof(int),
std::bind1st(std::not_equal_to<int>(), 0));
Basically, if the situation is that you need to move items that satisfy a condition to "one side" of a container, then the partition algorithm functions should be high up on the list of solutions to choose (if not the solution to use).
Upvotes: 16
Reputation: 38939
This is O(n) so it may be what he's looking for:
auto arrBegin = begin(arr);
const auto arrEnd = end(arr);
for(int i = 0; arrBegin < arrEnd - i; ++arrBegin){
if(*arrBegin == 0){
i++;
*arrBegin = *(arrEnd - i);
}
}
std::fill(arrBegin, arrEnd, 0);
Upvotes: 0
Reputation: 726879
An approach that sorts is O(N*Log2N). There is a linear solution that goes like this:
readPtr
and writePtr
, initially pointing to the beginning of the arrayreadPtr
up the array to the end. If *readPtr
is not zero, copy to *writePtr
, and advance both pointers; otherwise, advance only readPtr
.readPtr
is at the end of the array, walk writePtr
to the end of the array, while writing zeros to the remaining elements.Upvotes: 2