#面试题--找出数组中的唯一值
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(异或) | |
1 | 351 | 422 | 55 | 24 |
2 | 244 | 342 | 57 | 1 |
3 | 135 | 298 | 11 | 1 |
4 | 136 | 168 | 10 | 0 |
5 | 135 | 366 | 12 | 1 |
解法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
相关文章推荐
- 黑马程序员——java的集合类
- 蒋宇捷——程序员的进化 - 在拉勾1024程序员节上的演讲
- 剑指offer面试题7——用两个栈实现队列
- 展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告
- 冒泡排序——面试会经常被问到
- 何为码农?
- 程序员第一次软件实习需掌握的5大技巧
- 对新手程序员的唠叨
- 黑马程序员——基础知识总结_反射
- 面试题整理:C#(二)
- 新浪面试
- 99 位职业设计师 99 个设计谏言
- 黑马程序员——Java基础——内部类
- 面试题7:用两个栈实现队列
- 面试题21:包含min函数的栈
- 面试题19:二叉树的镜像
- 面试题10:二进制中1的个数
- 程序员必须知道的10大基础实用算法及其讲解
- 程序员必须知道的10大基础实用算法及其讲解 分类: 算法 2015-06-28 09:54 10人阅读 评论(0) 收藏
- 面试 :如何写一个满分的strcpy!!!