【算法14】找出数组中两个只出现一次的数字
2011-12-07 22:24
267 查看
【题 目】一个整型数组中除了两个数字外,其他的数字都出现两次。请找出这两个只在数组中出现一次的数字。要求时间复杂度O(n),空间复杂度O(1)。
【思 路】首先我们考虑一个稍微简单点的情况:如果这个数组中只有一个数字出现且仅出现一次,其他数字都出现两次,我们应该怎么样找出这个数字呢?我们题目说数字出现两次有什么深意呢?我们很容易联想到异或运算,因为任何一个数字和自身异或的结果为0;知道了这点,我们就很容易知道,我们将所有的数字进行异或,其结果就是仅出现一次的数字,因为其他所有的数字都两两异或为0了。
有了上面那个简单题目作为引子,我们很容易想到,如果我们将原题目的数组成功的分为两个子数组,而每个子数组恰好含有一个仅出现一次的数字,那么我们就可以根据上面的思路直接求解。怎么划分这两个子数组呢?
我们仍然将原数组中的所有数字进行异或运算,容易知道,异或的结果实际上就是两个仅出现一次的数字的异或结果,因为这两个数字不相等,所以异或的结果肯定不为0,我们可以找到异或结果中,第一个为1的位,这说明在该位上,必然有一个数字为1,另一个数字在该为上为0;我们可以按照这个结果,对所有该位上为1的数字分为一组,而将该位上为0的位分为另一组,这样我们就成功的讲原问题转换为两个简单的子问题。再对子问题全部异或,即可获得两个仅出现一次的数字。按照这个思路,我们可以得到如下的代码:
测试及运行结果如下:
References:
何海涛博客:http://zhedahht.blog.163.com/blog/static/2541117420071128950682/
注:
1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。
2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。
【思 路】首先我们考虑一个稍微简单点的情况:如果这个数组中只有一个数字出现且仅出现一次,其他数字都出现两次,我们应该怎么样找出这个数字呢?我们题目说数字出现两次有什么深意呢?我们很容易联想到异或运算,因为任何一个数字和自身异或的结果为0;知道了这点,我们就很容易知道,我们将所有的数字进行异或,其结果就是仅出现一次的数字,因为其他所有的数字都两两异或为0了。
有了上面那个简单题目作为引子,我们很容易想到,如果我们将原题目的数组成功的分为两个子数组,而每个子数组恰好含有一个仅出现一次的数字,那么我们就可以根据上面的思路直接求解。怎么划分这两个子数组呢?
我们仍然将原数组中的所有数字进行异或运算,容易知道,异或的结果实际上就是两个仅出现一次的数字的异或结果,因为这两个数字不相等,所以异或的结果肯定不为0,我们可以找到异或结果中,第一个为1的位,这说明在该位上,必然有一个数字为1,另一个数字在该为上为0;我们可以按照这个结果,对所有该位上为1的数字分为一组,而将该位上为0的位分为另一组,这样我们就成功的讲原问题转换为两个简单的子问题。再对子问题全部异或,即可获得两个仅出现一次的数字。按照这个思路,我们可以得到如下的代码:
#include<iostream> #include<string> using namespace std; //判断一个数number的第bitIndex位是否为1 bool IsBit1(int number,unsigned int bitIndex) { number = number>>bitIndex; return (number & 1); } //找到num中第一个位是1的位 unsigned int FindFirstbitOf1(int num) { int bitIndex = 0; while(bitIndex < 32 && ((num & 1) == 0)) { num = num>>1; bitIndex++; } //该函数的另一种循环结构,完全等价 /* for(bitIndex = 0;bitIndex < 32;++bitIndex,num = num>>1) { if((num & 1) ==1) break; } */ return bitIndex; } void FindNumbersAppearOnce(int data[],unsigned int length,int &num1,int &num2) { //无效输入 if(data == NULL || length < 2) return; //得到num1异或num2 int resultOfBitOR = 0; for(int i = 0;i < length;++i) { resultOfBitOR ^= data[i]; } //找到num1^num2的结果中第一个为1的位 unsigned int index = FindFirstbitOf1(resultOfBitOR); num1 = 0; num2 = 0; //将index位的取值是否为1分为两组 //将每一组的全部数字做异或 for(int j= 0;j < length;++j) { if(IsBit1(data[j],index)) num1 ^= data[j]; else num2 ^= data[j]; } } int main() { cout<<"Please Enter your ArrayLength:"<<endl; int arraylength = 0; cin>>arraylength; int *array = new int[arraylength]; cout<<"Please Enter the numbers in your Array:"<<endl; for(int k = 0;k < arraylength;++k) { cin>>array[k]; } int result1 = 0; int result2 = 0; FindNumbersAppearOnce(array,arraylength,result1,result2); cout<<"the numbers appear once in your array are:"<<endl; cout<<result1<<"\t"<<result2<<endl; return 0; }
测试及运行结果如下:
References:
何海涛博客:http://zhedahht.blog.163.com/blog/static/2541117420071128950682/
注:
1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。
2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。
相关文章推荐
- 算法习题61:找出数组中两个只出现一次的数字:一个整型数组里除了两个数字之外,其他的数字都出现了两次
- 每天一道算法题10 找出数组中两个只出现一次的数字
- 算法题6 找出整数数组中两个只出现一次的数字
- 程序员面试100题(算法)之找出数组中两个只出现一次的数字(位运算实现)
- 算法题:找出整数数组中两个只出现一次的数字
- 找出数组中两个只出现一次的数字 (算法)
- 每天一道算法题-1 找出数组中两个只出现一次的数字
- 算法--找出数组中两个只出现一次的数字
- 每天一道算法题10 找出数组中两个只出现一次的数字
- 微软面试之34 找出数组中两个只出现一次的数字 与 找出数组中一个只出现一次的数字
- 【每日面试题】找出数组中两个只出现一次的数字
- .一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。 找出这两个数字,编程实现。
- 程序员面试题精选(54):找出数组中两个只出现一次的数字
- 找出数组中一个(两个,三个)只出现一次的数字
- C语言- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次,找出这两个数字,编程实现。
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
- 一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字
- 找出数组中两个只出现一次的数字
- 【转帖】找出数组中两个只出现一次的数字
- 100题_34 找出数组中两个只出现一次的数字