Google Interview Question
Software EngineersCountry: Switzerland
Interview Type: Written Test
One way is to create a hash table with frequency of each integer and then search though it to find the non-compliant integer:
private static int find(int[] array) {
HashMap<Integer, Integer> frequencies = new HashMap<>();
for (int value : array) {
Integer frequency = frequencies.get(value);
if (frequency == null) {
frequencies.put(value, 1);
} else {
if (frequency == 3) {
return value;
}
frequencies.put(value, 1 + frequency);
}
}
for (int value : frequencies.keySet()) {
if (frequencies.get(value) != 3) {
return value;
}
}
return 0;
}
I don't see the necessity for the last loop. If there is an outlander, you will exit during the first one.
If they were asking to find all of them, then the "return" in the first loop has to be replaced with adding the outlander to the result structure, and I still don't see the need for the last loop.
public class FindMissingNumber {
public static void main(String[] args) {
int[] numbers = {3, 3, 4, 0, 10, 3, 0, 10, 0, 10, 4};
System.out.println(findMissing(numbers));
}
public static int findMissing(int[] numbers) {
Set<Integer> unique = new HashSet<>();
int uniqueSum = 0;
int realSum = 0;
for (int number : numbers) {
realSum += number;
if (!unique.contains(number)) {
uniqueSum += number;
unique.add(number);
}
}
return 3 * uniqueSum - realSum;
}
}
What if the array were
[0, 0] or [0, 0, 0, 1, 2, 2, 2] ? In those cases, I don't think your alg would work.
//Assuming that the integers in the array are unsorted. If more then one integer is found that doesn't repeat 3 times, only the first occurrence will be returned.
public class DuplicateService
{
public int findNonRepeat(int[] arr)
{
if(arr==null)
{
throw new NullPointerException("input array cannot be null");
}
if(arr.length<3)
{
return(arr[0]);
}
HashMap<Integer,Integer> counts=new HashMap<Integer,Integer>();
for(int i=0;i<arr.length;i++)
{
if(!counts.contains(arr[i]))
{
counts.put(arr[i],1);
}else
{
int count=counts.get(arr[i]).intValue();
count++;
counts.put(arr[i],count);
}
}
int result=0;
for(Map.Entry<Integer,Integer> e:counts)
{
int x=e.getValue();
if(x<3)
{
result=e.getKey().intValue();
}
return result;
}
}
}
If you got 2 of each, except for one. You could just xor the hole lot and then you would get the missing one.
Missing = Xor(all_others[i]) for all i from 0 to n-1;
xor (xor(n,x),x) == n
and
xor(n,x)== n
So you need some kind of a function such that
F(F(F(n,x),x ),x) == n
and
G(F(F(n,x),x)) == x
You should be able to do this with a little bit manipulation only storing 2 additional integers as well as a pointer into the array. These 2 integers are combined into try nary integer of the corresponding length. You add each integer to this number but you do not do any caries. When you add a 1 to on of these try nary (trits) it goes from 0 to 1 and then when you do it again it goes from 1 to 2 and then it goes back from 2 to 0. You do this for each bit in each number. If a number appears 3 times it will role that bace 3 digit around 3 times and not affect the result. But the digit that happens 2 times will role its bit to 2.
class Foo
{
public:
Foo(): a(0), b(0) { }
void put(int n)
{
int ap = ((~b) & (~a) & n) | ((~b) & a & (~n));
b = ((~b) & a & n) | (b & (~a) & (~n));
a = ap;
}
const int get()const
{
return b;
}
private:
int a,b;
};
/*
*
*/
int main(int argc, char** argv) {
Foo f;
f.put(12);
f.put(12);
f.put(12);
f.put(1);
f.put(1);
f.put(2);
f.put(2);
f.put(2);
cout << f.get();
return 0;
}
i think it is hard to understand... but it's really cool.
we can transform the integer to 32-bit, and use a array to store the sum of each bit. at last, mod 3 and all the bit is not 0 is the special num 's bit.
We can create a list ehich contains unique elements from input list. Then iterate over the unique list and check the count of number, if not 3 then add to return list
from sets import Set
def find_unmatched(list_num):
unmatched_list = []
unique_list = list(set(list_num))
for number in unique_list:
if list_num.count(number) != 3:
unmatched_list.append(number)
return unmatched_list
Here is my solution using bit manipulation:
public int findNumber(int[] nums) {
int ones = 0, twos = 0, threes = 0;
for (int i = 0; i < nums.length; i++) {
int x = nums[i];
twos |= ones & x;
ones ^= x;
threes = ones & twos;
ones &= ~threes;
twos &= ~threes;
}
return ones | twos;
}
ones holds the numbers that appear once, twos holds the number that appear twice, threes holds the numbers that appear three times.
Sample solution in C++
#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;
int findDifferent(const vector<int>& v) {
unordered_map<int, int> m;
for (const auto n : v) {
++m[n];
}
for (const auto& p : m) {
if (p.second != 3) {
return p.first;
}
}
return -1;
}
int main() {
vector<int> v {1,2,3,1,2,3,1,2,3,2};
int different = findDifferent(v);
cout << different << endl;
return 0;
}
This method uses bitwise operators .It works for all inputs except when the said element is present in multiple of 3.
- Klaus July 21, 2015