Amazon Interview Question
Software Engineer in TestsCountry: India
Interview Type: Phone Interview
last line of algorithm does not lead to result...so problem is, how could we find two numbers by knowing their XOR.
Hey Minku,
The algo dfinitely leads us to result. You will be XORing two different sets and each of them will have the two numbers separately. I am posting my implementation.
public class Main {
public static void main(String[] args) {
int a[]={2,3,2,3,3,4,5,4,2,2,5,6};
Integer XOR = null;
for(int i=0;i<a.length;i++){
if(XOR==null)
XOR=a[i];
else
XOR^=a[i];
}
int position=findFirstBitWithSetBit(XOR);
Integer XOR0=null, XOR1=null;
for(int i=0;i<a.length;i++){
if(getBitAtPosition(a[i], position)==0){
if(XOR0==null)
XOR0=a[i];
else
XOR0^=a[i];
}else{
if(XOR1==null)
XOR1=a[i];
else
XOR1^=a[i];
}
}
System.out.println(XOR0);
System.out.println(XOR1);
}
public static int getBitAtPosition(int x, int position){
return (x>>position)&;1;
}
public static int findFirstBitWithSetBit(int x){
int position=0;
while((x&;1)!=1){
position++;
x=x>>;1;
}
return position;
}
}
Time Complexity: O(n)
Space Complexity: O(1)
It took me a few minutes to grasp how he dragged the numbers out of the XORed bits.
The trick to it is that because we're trying to find the two numbers that was set in an ODD number of times.
So, if the bit was a "1". 1 XOR 1 = 0 XOR 1 = 1
So if there is a 1 in the XORed bit set, and because the sum of two odd numbers is always even. Anything XORed an even number of times. = 0
Thus, for all 0's in the XORed bit set, there must have been 1 in the original bits. And for all 1's in the XORed bit set, both original bit sets have to contain a 0 or 1 respectively.
int x(0), y, a(0), b(0);
for (auto i : A)
x = x ^ i;
y = (x & -x);
for (auto i : A)
if (y & i) a = a ^ i;
else b = b ^ i;
cout << a <<' '<< b << endl;
Time Complexity: O(n)
Space Complexity: O(1)
Simpler solution at the cost of space:
- Create a hash set
- Loop the integers
-- If the element is in the hash set, remove it
-- Otherwise, add it (since it's not already present)
- The answer is the contents of the hash set (which scales to any number of odd numbers)
Complexity: O(n) (due to an O(1) get/put hash set).
Correct...
in case we do not want to us collections....
we can have an Array of size [unique occurrence of elements]
with a simple logic to check 'If the element is not present in Array add it otherwise remove the occurrence in Array.
public List<Integer> findNumbers(int[] a) {
List<Integer> list = new ArrayList<Integer>();
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i=0; i<a.length; i++) {
Integer key = new Integer(a[i]);
if (map.containsKey(key)){
Integer count = new Integer(map.get(key).intValue() + 1);
map.put(key, count);
} else {
map.put(new Integer(a[i]), new Integer(1));
}
}
for(Integer key: map.keySet()) {
Integer value = map.get(key);
if (value.intValue()%2 != 0) {
list.add(key);
}
}
return list;
}
Hey Satyajeet here you go. Should work without any change. Please let me know as I could not verify this.
public class Main {
public static void main(String[] args) {
int a[]={2,3,2,3,3,4,5,4,2,2,5,6};
Integer XOR = null;
for(int i=0;i<a.length;i++){
if(XOR==null)
XOR=a[i];
else
XOR^=a[i];
}
int position=findFirstBitWithSetBit(XOR);
Integer XOR0=null, XOR1=null;
for(int i=0;i<a.length;i++){
if(getBitAtPosition(a[i], position)==0){
if(XOR0==null)
XOR0=a[i];
else
XOR0^=a[i];
}else{
if(XOR1==null)
XOR1=a[i];
else
XOR1^=a[i];
}
}
System.out.println(XOR0);
System.out.println(XOR1);
}
public static int getBitAtPosition(int x, int position){
return (x>>position)&1;
}
public static int findFirstBitWithSetBit(int x){
int position=0;
while((x&1)!=1){
position++;
x=x>>1;
}
return position;
}
}
Time Complexity: O(n)
Space Complexity: O(1)
My java solution in O(n):
import java.util.*;
public class Array_Odd_Occ {
public static void main(String[] args) {
int a[]={2,3,2,3,3,4,5,4,2,2,5,6};
findNumbers(a);
}
private static void findNumbers(int [] a) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < a.length; i++) {
Integer freq = map.get(a[i]);
map.put(a[i], (freq == null) ? 1 : freq + 1);
}
for(Map.Entry<Integer, Integer> nums : map.entrySet()) {
if(nums.getValue() % 2 != 0)
System.out.println(nums.getKey());
}
}
}
Output:
3 6
package linearData;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
public class OddOneOut {
public static void main(String[] args) {
int a[] = {1,2,3,4,2,1,3,6,6,6};
int length = a.length;
HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
for(int i = 0; i < length; i++ )
{
if(hm==null)
{
hm.put(1, a[i]);
}
else
{
if(hm.containsKey(a[i]))
{
int val = hm.get(a[i]);
val++;
hm.put(a[i], val);
}
else
hm.put(a[i], 1);
}
}
Set s = hm.entrySet();
//Map<T, E> map
for (Entry<Integer, Integer> entry : hm.entrySet()) {
if (entry.getValue()%2!=0) {
System.out.println(entry.getKey());
}
}
}
}
#You are given an integer array, where all numbers except for
#TWO numbers appear even number of times.
#Q: Find out the two numbers which appear odd number of times.
intarr = [1,2,3,4,5,6,7,8,9,10,1,2,4,5,6,7,8,9]
def find_two_ints_not_even(intlist):
odd_int={}
retlist=[]
for _int in intlist:
if _int in odd_int:
odd_int[_int]=odd_int[_int]+1
else:
odd_int[_int]=1
for val1 in odd_int:
if odd_int[val1] % 2 == 1:
retlist.append(val1)
if len(retlist)==2:
return retlist
return retlist
print find_two_ints_not_even(intarr)
Keep a hashmap with the integers as keys. Delete repeats (evens). O(n) time, but uses additional space, up to about almost n. There could be a lot of unique (1-count) entries.
function findOddAppearances(list) {
var numMap = {};
list.forEach(function(num) {
if (numMap[num]) {
delete numMap[num];
} else {
numMap[num] = true;
}
});
return Object.keys(numMap);
}
var input = [0,0, 1,1, 2,2,2, 3,3, 4,4,4,4, 5,5,5, 6,6];
console.log(findOddAppearances(input)); // => [2,5];
using Javascript object
var array = [2, 3, 2, 3, 3, 4, 5, 4, 2, 2, 5, 6];
var count = {};
var result = {};
array.forEach(item => {
if (count[item]) {
count[item] = count[item] + 1;
} else {
count[item] = 1;
}
if (count[item] % 2 !== 0) {
result[item] = count[item];
} else {
delete result[item];
}
});
Time Complexity: O(n)
1. XOR all the n numbers.
2. Result will be knocked out for all the even pairs as a^a=0 The result now contains only XOR of the two odd out numbers.
3. Find the first bit position in the result that is 1. Definitely this bit position both the odd numbers have different bit values. i.e. one has a 0 and another has a 1 at this position. Let this position be x
4. XOR the elements that have 1 at x bit position and XOR the elements that have 0 at x bit position. The two XOR results would give the two odd count numbers.
If you really find some answer helpful, please up-vote. It helps people in finding valid answers. :)
@Expressions: Unregistered users cannot vote I believe. But there is a bigger problem. This should be a comment on the answer for which it was intended.
1. XOR all the n numbers.
- Expressions March 27, 20132. Result will be knocked out for all the even pairs as a^a=0 The result now contains only XOR of the two odd out numbers.
3. Find the first bit position in the result that is 1. Definitely this bit position both the odd numbers have different bit values. i.e. one has a 0 and another has a 1 at this position. Let this position be x
4. XOR the elements that have 1 at x bit position and XOR the elements that have 0 at x bit position. The two XOR results would give the two odd count numbers.