面试遇见的算法题,进行一下系统总结学习
2017-08-18 21:55
423 查看
参见百度云事业部的面试,遇见的一道题目,进行学习总结。题外话:百度云面试官的特别有耐心,友好,如果面试遇见不会解决的问题还会告诉你解决思路便你以后学习。点赞!!!
题目:数组A中,除了某一个数字x之外,其他数字都出现了2次,而x出现了一次。请给出最快的方法找到x。
方案1分析:
当时第一思路就是使用Set进行计算,通过一遍循环计算出。代码实现:
很简单,就不具体细说了。
方案2分析:
方案2是面试官给的思路,说异或运算符进行求解。分析思路:由于异或操作特性,两个相同的数异或值为0入手,对数组两两数进行异或最后的值就是单独的数值,代码实现如下:
这种算法可以解决多种类似题目,例如题目拓展为:数组A中,除了某一个数字出现奇数次之外,其他数字都出现了偶数次,请给出最快的方法找到出现奇数的数值。
例如测试用例可以:
如果题目在拓展:数组A中,除了某一个数字出现m次之外,其他数字都出现了n次,请给出最快的方法找到出现m次的数值。
当m为偶数,n为奇数情况下,如上办法就不可使用了,所以接下来写出一个更具有普遍性的算法:
测试用例:
此算法注意二维数组的行列搞清楚就很容易实现,有时很容易因为二位数组行列混淆导致出问题,此处附赠一张java二位数组的内存布局图:
题目:数组A中,除了某一个数字x之外,其他数字都出现了2次,而x出现了一次。请给出最快的方法找到x。
方案1分析:
当时第一思路就是使用Set进行计算,通过一遍循环计算出。代码实现:
public static int getSingleNumberWithSet(int[] args) { Set<Integer> set = new HashSet<>(); for (int i : args) { if (!set.contains(i)) { set.add(i); } else { set.remove(i); } } return set.size() == 1 ? set.iterator().next() : -1; }
很简单,就不具体细说了。
方案2分析:
方案2是面试官给的思路,说异或运算符进行求解。分析思路:由于异或操作特性,两个相同的数异或值为0入手,对数组两两数进行异或最后的值就是单独的数值,代码实现如下:
/** * 实现思路1。这种实现思路适合大多数出现偶数次,找出现奇数次的 <br> * <br> * 还有其他思路就是将数组每一个数转成二进制数的矩阵,按列除以2,如果整除改为为,不整除改为为1。最后统计结果即可 * * @param args * @return 出现一次的数值 */ public static int getSingleNumber(int[] args) { if (args == null) return -1; String num = Integer.toBinaryString(args[0]);// 将int转成2进制字符串 for (int i = 1; i < args.length; i++) num = Integer.toBinaryString(Integer.parseInt(num, 2) ^ args[i]);// 两两数逐渐做异或,最后就是那个单独的数 return Integer.parseInt(num, 2); }
这种算法可以解决多种类似题目,例如题目拓展为:数组A中,除了某一个数字出现奇数次之外,其他数字都出现了偶数次,请给出最快的方法找到出现奇数的数值。
例如测试用例可以:
public static void main(String[] args) { int[] nums = { 1, 4, 2, 2, 3, 3, 1, 4, 5 };// 如何快速查找出来出现一次的数 int[] nums1 = { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3 }; System.out.println(getSingleNumber(nums1)); }
如果题目在拓展:数组A中,除了某一个数字出现m次之外,其他数字都出现了n次,请给出最快的方法找到出现m次的数值。
当m为偶数,n为奇数情况下,如上办法就不可使用了,所以接下来写出一个更具有普遍性的算法:
/** * @author daxin * @email leodaxin@163.com * @param args * 指定的数组 * @param count * 其他数字均出现的次数为count * @param find * 寻找出现find次的数值 * @return find次的数值 */ public static int get(int[] args, int count, int find) { //如果find大于等于count时候会出现错误:例如count=2,find=5,计算余数时候:x%count永远无法等于5 if (args == null || find >= count) return -1; Arrays.sort(args);// 数组排序为了寻找最大值 int maxValue = args[args.length - 1]; int len = Integer.toBinaryString(maxValue).length();// 计算最大数值的二进制需要占用多少位,然后创建对应“行长”的二位数组 int[][] matrix = new int[len][args.length];// 二位数组 for (int i = 0; i < matrix[0].length; i++) { // 填充数组 char[] chars = Integer.toBinaryString(args[i]).toCharArray(); int chLen = chars.length - 1; for (int j = matrix.length - 1; j >= 0; j--) {// 控制列 matrix[j][i] = Character.getNumericValue(chars[chLen--]);//或者val-'0'这么写 if (chLen < 0) { break; } } } int[] result = new int[len]; for (int i = 0; i < matrix.length; i++) {// 进行按列统计 int columCount = 0; for (int j = 0; j < matrix[0].length; j++) { if (matrix[i][j] == 1) columCount++; } if (columCount % count == find) // 取余数计算 result[i] = 1; else result[i] = 0; } StringBuilder sb = new StringBuilder(); for (int i = 0; i <result.length; i++) { sb.append(result[i]); } return Integer.parseInt(sb.toString(), 2); }
测试用例:
int[] nums0 = { 1, 4, 2, 2, 3, 3, 1, 4, 5 };// 如何快速查找出来出现一次的数 int[] nums1 = { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3 }; int[] nums2 = { 1, 1, 1, 2, 2, 2, 3, 3 }; int[] nums3 = { 11, 3, 8, 8, 3 }; int[] nums4 = { 2, 2, 2, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3 }; System.out.println("期望值 = "+5+" 实际值 = "+get(nums0, 2, 1)); System.out.println("期望值 = "+3+" 实际值 = "+get(nums1, 4, 3)); System.out.println("期望值 = "+3+" 实际值 = "+get(nums2, 3, 2)); System.out.println("期望值 = "+11+" 实际值 = "+get(nums3, 2, 1)); System.out.println("期望值 = "+2+" 实际值 = "+get(nums4, 5, 3));
此算法注意二维数组的行列搞清楚就很容易实现,有时很容易因为二位数组行列混淆导致出问题,此处附赠一张java二位数组的内存布局图:
相关文章推荐
- HashMap与Hashtable的区别是面试中经常遇到的一个问题。这个问题看似简单,但如果深究进去,也能了解到不少知识。本文对两者从来源、特性、算法等多个方面进行对比总结。力争多角度、全方位的展示二者的不同,做到此问题的终结版。
- 系统算法学习总结
- [学习总结][算法]用插入排序对一个链表进行排序
- java面试准备---JSF系统学习知识点总结---随时更新
- 什么是系统,什么是算法 -- lemon OA 系统学习总结
- java面试准备---JSF系统学习知识点总结---随时更新
- July大神关于面试中算法学习的总结
- 主要推荐系统算法总结及Youtube深度学习推荐算法实例概括
- 系统学习机器学习之SVM(四)--SVM算法总结
- gwt 学习总结一下。
- Cisco 3750文件系统学习总结
- 总结一下维护了一年的一个软件系统的软件体系(三)
- 搜索引擎系统学习与开发实践总结
- 总结一下维护了一年的一个软件系统的软件体系(四)
- Cisco 3750文件系统学习总结
- 我来介绍一下"反向传播学习算法"和"梯度下降法"
- 搜索引擎系统学习与开发实践总结
- 好文莫过于此:搜索引擎系统学习与开发实践总结(张合福的专栏)
- 系统地学习ASP.NET AJAX(1) - 简单地过一下每个控件
- 总结一下这几天的学习成果