6.3:一个数组中有两种数出现了奇数次,其它数出现了偶数次,怎么找到并打印这两种数
6.3:一个数组中有两种数出现了奇数次,其它数出现了偶数次,怎么找到并打印这两种数
两种数出现奇数次,其它偶数次
1、用eor = 0去逐个异或,最后一定是 eor = a^b, a和b是这个两个出现奇数次的数。偶数次异或为0。
2、a != b, eor != 0; eor的binary一定有1,利用6.2,提取最右侧的那个1的方法。
说明a和b的二进制数在这个位置一定是不一样的。
数组里的所有数分为2类
第i位置是1的数
第i位置是0的数
3、在定义eor`去异或这个数组,只挑选第i为是1的数去异或,是0的数不碰。
eor`会把a拽出来
4、另一个 = eor^eor`
6 00110
10 01010
4 00100
12 01100
3 00011
[6, 10, 6, 6, 4, 4, 12, 12, 12, 12, 3, 3]
eor异或所有后 = 6^10,偶数都为0
6 00110
异或 10 01010
-------------------------------
01100 就拿最右边的1来观察
把第二位上有1的数分类
有1的数[ 6, 4, 12 ] 无1的数[10, 3]
用eor`去异或第二位上有1的数,成功躲掉10、3, 在6,4,12中,4和12是偶数的,eor`=6。
另一个 = eor^eor`
1 public static void printOddTimesNum1(int[] arr) { 2 int eor = 0; 3 for (int i = 0; i < arr.length; i++) { 4 eor ^= arr[i]; 5 } 6 System.out.println(eor); 7 } 8 9 // arr中,有两种数,出现奇数次 10 public static void printOddTimesNum2(int[] arr) { 11 int eor = 0; 12 for (int i = 0; i < arr.length; i++) { 13 eor ^= arr[i]; 14 } 15 // a 和 b是两种数 16 // eor != 0 17 // eor最右侧的1,提取出来 18 // eor : 00110010110111000 19 // rightOne :00000000000001000 20 int rightOne = eor & (-eor); // 提取出最右的1 21 22 23 int onlyOne = 0; // eor' 24 for (int i = 0 ; i < arr.length;i++) { 25 // arr[1] = 111100011110000 26 // rightOne= 000000000010000 27 if ((arr[i] & rightOne) != 0) { //这个arr[i]在最右侧的位置上一定为1 28 onlyOne ^= arr[i]; 29 } 30 } 31 System.out.println(onlyOne + " " + (eor ^ onlyOne)); 32 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现