您的位置:首页 > 职场人生

#面试题--找出数组中的唯一值

2015-06-28 16:35 501 查看

#面试题 找出数组中的唯一值

数组中仅有一个元素出现了一次, 其他元素均出现了两次, 找出其中的唯一值, 如数组: [3 4 5 2 3 4 5], 2只出现了一次,即要找出2.

解法1(sort):

/**
* 算法1
* 1. 先排序
* 2. 若a[i+1]!=a[i] (i为偶数)或a[i+1]不存在 则a[i]为唯一元素
*
* [3 4 5 2 3 4 5]
* [2 3 3 4 4 5 5]
* a[1]!=a[0] ==> a[0]为唯一元素
*
* [3 4 5 2 2 4 5]
* [2 2 3 4 4 5 5]
* a[3]!=a[2] ==> a[2]为唯一元素

* [3 4 5 2 2 4 3]
* [2 2 3 3 4 4 5]
* a[7]不存在 ==> a[6]为唯一元素
* @param a
*/
public static int findUniqueValue1(final int[] a){
int[] b = a.clone();
Arrays.sort(b);
int result = -1;
for (int i = 0; i < b.length; i+=2) {
if(i+1==b.length || b[i+1]!=b[i]){
result = b[i];
break;
}
}
return result;
}


解法2(map):

/**
* 算法2
* 利用 map<a[i], null>
* 如果key(a[i])已存在 直接删除 若不存在 添加
* 最后剩下唯一的key即为所求的唯一元素
* @param a
*/
public static int findUniqueValue2(final int[] a){

Map<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < a.length; i++) {
if(map.containsKey(a[i]))
map.remove(a[i]); //off
else
map.put(a[i], null); //on
}
int result = -1;
for (Integer key : map.keySet())
result = key;
return result;
}


解法3(位数组):

/**
* 算法3
* 利用位数组 Bit[] bits
* 如果key(a[i])不存在 bits[a[i]]=1 若已存在 bits[a[i]]=0
* 最后bits数组中等于1的索引值即为所求值
* 如
* 数组 a: [3 4 5 2 3 4 5]
*
* init bit array: [0 0 0 0 0 0]
* [0 0 0 1 0 0]
* [0 0 0 1 1 0]
* [0 0 0 1 1 1]
* [0 0 1 1 1 1]
* [0 0 1 0 1 1]
* [0 0 1 0 0 1]
* [0 0 1 0 0 0]
* @param a
* @param max 数组中的最大值
*/
public static int findUniqueValue3(final int[] a, int max){
BitSet bitSet = new BitSet(max);
for (int i = 0; i < a.length; i++){
bitSet.flip(a[i]);
}
int result = -1;
for (int i = 0; i <= max; i++) {
if(bitSet.get(i)){
result = i;
break;
}
}
return result;
}


解法4(异或):

/**
* 算法4
* 利用自己与自己异或为0的特点 如 3 ^ 3 = 0
* [3 4 5 2 3 4 5]
* 3^4^5^2^3^4^5=2
* @param a
*/
public static int findUniqueValue4(final int[] a){
int t=a[0] ;
for (int i = 1; i < a.length; i++)
t ^= a[i];
return t;
}


下面是对上述四种算法的性能比较:

算法1(sort)算法2(map)算法3(bit array)算法4(异或)
135142255
24
2244342571
3135298111
4136168100
513536612
1
注: 数组大小为1,000,001, 一共运行了5次, 在循环内部分别调用上述4个方法,每个调用之间休眠1秒,运行时间单位是毫秒(ms)

解法5(linux uniq):

利用LInux命令, 如下所示:

$ cat uniq_test.txt
3
4
5
2
3
4
5
$ sort uniq_test.txt | uniq -u
2

同样测试在1,000,001行的文件中寻找唯一值时的花费,

$ cat find_uniq_value_test.txt | wc -l
1000001
$ time sort find_uniq_value_test.txt | uniq -u
1000001

real    0m2.907s
user    0m9.426s
sys 0m0.039s

需要2秒多.

补充:

构造一个满足要求的测试文本的shell命令

$ seq 1 2 10
1
3
5
7
9
$ seq 1 2 10 > temp.txt
$ seq 1 2 10 >> temp.txt
$ echo 11 >> temp.txt
$ cat temp.txt
1
3
5
7
9
1
3
5
7
9
11
$ shuf temp.txt
7
3
5
11
1
1
5
9
7
9
3
$ shuf temp.txt > temp_shuf.txt
$ sort -n temp_shuf.txt | uniq -u
11

参考了:

http://x-wei.github.io/%E6%89%93%E4%B9%B1%E6%96%87%E6%9C%AC%E7%9A%84%E8%A1%8C.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: