异形数问题-剑指offer40题
来源:互联网 发布:rgbcolor.js 编辑:程序博客网 时间:2024/05/12 11:58
一个整形数组中,除了两个数外,其他每个数都出现2次,找出只出现了一次的那两个数?
分析:一般用异或的方法来去掉重复出现的数,两个相同的数进行异或运算后等于0,并且异或操作满足交换律和结合律。
如果一个数组中只有一个数字单独出现过一次,其他数字都分别出现过两次,那么用0异或数组中每一个元素就可以得到唯一出现过一次那个元素。
思路:把整个数组分为两部分,每个部分都包含一个只出现过一次的元素和若干对重复元素,分别求出这两个子数组中的唯一元素即可。
1. 首先用0依次异或数组中每一个元素,因为相同的元素异或得到0,所以最终的答案就等于那2个唯一的元素a^b的值。
2. 因为a,b不同,所以异或得到的答案肯定是不等于0的,那么我们就找到a^b的二进制表示中第一个为1的位,假如是第k位。而a,b两个数在第k位上是不同的,一个为0,一个为1
3. 接下来我们将第k位是1的分成一组,第k位是0的分成一组,如果2个元素相同,那么他们第k位肯定是一样的,所以肯定被分到同一组中。而a,b则被分到2组中去了。
然后我们就可以在每个分组中异或每一个元素,最终就可以得到那2个唯一的元素。
java代码如下:
/** * 得到num的二进制数中第一个为1的位的位置的函数 * @param num * @return 二进制数中1出现的最低位的位置 */ public static int getFirstOnePos(int num){ int pos = 1; //找到num的二进制数中第一个为1的位的位置 while((num&0x01)==0){ num = num>>1; pos++; } return pos; } /** * 用来分组的函数 * 如果地pos位为1,那么返回true。 * @param num 要进行分组的数 * @param pos 位置 * @return */ public static boolean divide(int num,int pos){ num = num>>(pos-1); return (num&0x01)==1?true:false; } /** * 查找出数组中两个只出现过一次的数 * @param a 要查找的数组 * @param n 数组长度 */ public static void find(int[] a,int n){ int num1 = 0; int num2 = 0; int povit = 0; //0异或数组中每一个元素,得到那两个只出现过一次的元素的异或值 for(int i=0;i<n;i++){ povit ^= a[i]; } //找到a^b的二进制表示中第一个为1的位置 int pos = getFirstOnePos(povit); for(int i=0; i<n; i++){ //分组 //第一组是pos位为1的 if(divide(a[i],pos)){ //用异或求出改组中唯一出现过一次数 num1 ^= a[i]; } else{ //第二组是pos位为0的 num2 ^= a[i]; } } System.out.println(num1); System.out.println(num2); }
0 0
- 异形数问题-剑指offer40题
- 剑指offer40题(平衡二叉树)
- 2013小米笔试题--异形数
- [小米] 异形数
- 小米校招编程题:数组乘积、异形数、朋友圈
- 2013 小米校园招聘笔试题之 找异形数
- 只出现一次的数字(剑指offer40)
- 剑指offer40--n个骰子点数和的概率
- 剑指offer40:数组中只出现一次的数字
- 剑指offer40——数组中只出现一次的数字
- HNACM(六) 第一题 异形卵
- 异形窗体
- 异形卵
- 异形卵
- 异形卵
- 异形卵
- 异形滚动
- GTK异形窗口;异形组件
- Deluge之重编程
- 从应用层通过aidl调用到frameworks中添加的服务的方法
- 数据分析能力的8个等级
- unity3d协作过程中svn的应用
- jfinal下项目路径获取
- 异形数问题-剑指offer40题
- Android 圆形进度条
- Unity中Quaternion的含义及其使用
- 李红霞作业第三章第10题
- 正则表达式
- 程序员面试之九阴真经
- 既不是P也不是NP完全的NP问题
- Android平台和java平台 DES加密解密互通程序及其不能互通的原因
- XML, JSON