找出数组中两个只出现一次的数字 【微软面试100题 第六十一题】
题目要求:
一个整型数组里除了两个数字机之外,其他的数字都出现了两次。
请写程序找出这两个只出现一次的数字。要求时间复杂度O(N).空间复杂度O(1).
参考资料:剑指offer第40题。
题目分析:
已知:
1.两个相同的数字异或的结果为0,即a^a = 0.
2.两个不相同的数字异或的结果的二进制中某一位为1,则这两个数字的二进制中对应位一个为0,一个为1.如3^2 = 1,对于最低位的二进制,3的最低位二进制为1,2的最低位二进制位0,则结果1的最低位二进制肯定为1.
假设原数组中只出现一次的两个数为a和b,则,原数组所有元素异或的结果c,即为a^b的结果(因为其他异或都为0),即a^b = c;
根据已知条件2,我们从c中找到其二进制中为1的位,把原数组分成两个部分X和Y(a和b分别在X和Y中,且X和Y中分别都是只有一个数字出现一次,其他数字出现两次),则X中的所有元素异或的结果肯定为a,Y中所有的元素异或的结果肯定为b,即为所求。
代码实现:
#include <iostream> using namespace std; const int N = 6; bool FindNumsAppearOnce(int data[],int len,int &num1,int &num2); int main(void) { int data[N] = {4,2,6,2,4,5}; // int data[N] = {4,2,6,2,4,6}; int num1,num2; if(FindNumsAppearOnce(data,N,num1,num2)) { cout << "num1 = "<< num1 << ",num2 = " << num2 << endl; } else cout << "不满足情况" << endl; return 0; } unsigned int FindFirstBitIs1(int num) { int index = 0; while((num&1)==0 &&(index<8*sizeof(int))) { num >>= 1; ++index; } return index; } bool IsBit1(int num,unsigned int index) { num >>= index; return (num&1); } bool FindNumsAppearOnce(int data[],int len,int &num1,int &num2) { if(data==NULL || len<2 || ((len&0x01)==1)) return false; int result =0; for(int i=0;i<len;i++) result ^= data[i]; if(result==0) return false; unsigned int index = FindFirstBitIs1(result); num1 = num2 = 0; for(int j = 0;j<len;j++) { if(IsBit1(data[j],index)) num1 ^= data[j]; else num2 ^= data[j]; } return true; }
很多时候不是我们做不好,而是没有竭尽全力......
分类:
【微软面试100题】
posted on 2014-11-17 10:19 tractorman 阅读(215) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?