【算法】求数组中出现了奇数次的一种/俩种数(异或运算)
左程云算法与数据结构课 https://www.bilibili.com/video/BV13g41157hK?p=2&spm_id_from=pageDriver
题目描述
在一个数组中,
(1)有一种数出现了奇数次,其余数出现了偶数次,求出现了奇数次的那种数。
(2)有俩种数出现了奇数次,其余数出现了偶数次,求出现了奇数次的俩种数。
题解
(1)一批数进行异或,与异或的顺序无关。
对数组的所有数进行异或,出现偶数次的数进行异或之后是0,出现奇数次的那种数异或之后还是那个数,所以最终异或结果是出现奇数次的那种数。
例如:数组[1,1,2,3,4,2,3,1,4]中除了1出现了奇数次外其余数均出现了偶数次,对数组元素进行异或,1^1^2^3^4^2^3^1^4=1^1^1^2^2^3^3^4^4=1
public static void printOddTimesNum1(int[] arr) {
int eor = 0;
for (int cur : arr) {
eor ^= cur;
}
System.out.println(eor);
}
(2)假设出现了奇数次的俩种数分别是a和b。
对数组元素进行异或,最终结果是a^b。
由于a不等于b,故a^b的二进制中至少有一位为1,假设是第n位为1。
对数组中第n位为1的元素进行异或(以第n位是否为1,可以把数组分成两份,a和b分别落于这两份之中),则结果为出现了奇数次的俩种数中的一种,然后让它和a^b进行异或,则可以求出另一种出现了奇数次的数。
public static void printOddTimesNum2(int[] arr) {
int eor1 = 0,eor2 = 0;
for (int cur : arr) {
eor1 ^= cur;
}
//eor1 = a ^ b
//eor1!=0,其二进制中至少有一个位置为1
// 提取出最右的1
int rightOne = eor1 & (~eor1+1);
for (int cur : arr) {
if ((cur & rightOne) == 1) { //只有第n位是1的才进行异或
eor2 ^= cur;
}
}
System.out.println(eor2 + " " + (eor1 ^ eor2));
}
本文来自博客园,作者:hzyuan,转载请注明原文链接:https://www.cnblogs.com/hzyuan/p/15760173.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)