面试题40:数组中只出现一次的数字
2016-07-19 08:21
369 查看
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果。因为其他数字都出现了两次,在异或中全部抵消掉了。由于这两个数字肯定不一样,那么这个异或结果肯定不为0,也就是说在这个结果数字的二进制表示中至少就有一位为1。我们在结果数字中找到第一个为1的位的位置,记为第N位。现在我们以第N位是不是1为标准把原数组中的数字分成两个子数组,第一个子数组中每个数字的第N位都为1,而第二个子数组的每个数字的第N位都为0。
现在我们已经把原数组分成了两个子数组,每个子数组都包含一个只出现一次的数字,而其他数字都出现了两次。
代码的关键是:1. 不合法条件是length < 2 2. indexBit < 8 * sizeof(int) 最多是第31位为1
自己的解
从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果。因为其他数字都出现了两次,在异或中全部抵消掉了。由于这两个数字肯定不一样,那么这个异或结果肯定不为0,也就是说在这个结果数字的二进制表示中至少就有一位为1。我们在结果数字中找到第一个为1的位的位置,记为第N位。现在我们以第N位是不是1为标准把原数组中的数字分成两个子数组,第一个子数组中每个数字的第N位都为1,而第二个子数组的每个数字的第N位都为0。
现在我们已经把原数组分成了两个子数组,每个子数组都包含一个只出现一次的数字,而其他数字都出现了两次。
代码的关键是:1. 不合法条件是length < 2 2. indexBit < 8 * sizeof(int) 最多是第31位为1
unsigned int FindFirstBitIs1(int num); bool IsBit1(int num, unsigned int indexBit); void FindNumsAppearOnce(int data[], int length, int* num1, int* num2) { if (data == NULL || length < 2) return; int resultExclusiveOR = 0; for (int i = 0; i < length; ++ i) resultExclusiveOR ^= data[i]; unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR); *num1 = *num2 = 0; for (int j = 0; j < length; ++ j) { if(IsBit1(data[j], indexOf1)) *num1 ^= data[j]; else *num2 ^= data[j]; } } // 找到num从右边数起第一个是1的位 unsigned int FindFirstBitIs1(int num) { int indexBit = 0; while (((num & 1) == 0) && (indexBit < 8 * sizeof(int))) { num = num >> 1; ++ indexBit; } return indexBit; } // 判断数字num的第indexBit位是不是1 bool IsBit1(int num, unsigned int indexBit) { num = num >> indexBit; return (num & 1); }
自己的解
void FindNumsAppearOnce(vector<int> data, int* num1, int *num2) { int len = data.size(); if (len <= 1) return; if (len == 2) { *num1 = data[0]; *num2 = data[1]; return; } int yihuo = 0; for (int i = 0; i < len; i++) yihuo ^= data[i]; int is_one = 1; while (!(is_one & yihuo)) is_one <<= 1; *num1 = 0; *num2 = 0; for (int i = 0; i < len; i++) { if (data[i] & is_one) *num1 ^= data[i]; if (!(data[i] & is_one)) *num2 ^= data[i]; } }
相关文章推荐
- iOS面试题总结(一)
- 你为什么找不到女朋友——致程序员
- 说说 IT 技术人的职业规划
- 硅谷女员工公开吐槽工资低被开除 但这只是开始(很现实的情况,但我觉得要归咎于房租太贵,以及自己的职业生涯计划不合理)
- Java面试参考指南——同步
- 面试问题:发一个随机红包,100块钱给10个人。每个人最多12块钱,最少6块钱。怎么分?
- 剑指offer之面试题22:二叉搜索树的后序遍历序列
- 数组循环移位
- MyBatis面试题
- 面试相关知识收集
- 国内一线互联网公司内部面试题库
- 面试,学会这些就足够啦!!!
- 十大必备面试问题 你知道多少???
- 转行做程序员之前你应该考虑的三件事
- 程序员接私单怎么接?,流程,报价。
- 转行做程序员之前你应该考虑的三件事
- Java JVM 请别拿“String s=new String("z");创建了多少实例”来面试 [ 转载 ]
- 常见的面试题总结
- 【面试总结】初探CLR
- PHP程序员进阶学习书籍参考指南