【算法】元素重复三次的数组中查找重复一次的元素

在给定的数组中,除一个元素外其他元素都重复三次,利用位运算在O(1)空间复杂度和O(n)时间复杂度下找出重复一次的元素。解题思路涉及声明firstAppear和secondAppear变量,通过位运算在每次元素出现时更新这两个变量,最终firstAppear将包含只出现一次的元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

元素重复三次的数组中查找重复一次的元素

题目:

给定一个大数组,它里面除了一个元素外,其他元素都重复了三次,要求在空间复杂度为O(1), **时间复杂度为O(n)**的约束下,查找到只重复了一次的元素。
意思就是说:这意味着算法必须对数组遍历1次就要找出给定元素。

解题思路

参考位图算法,

  • 声明两个变量 firstAppear(FA) 和 secondAppear(SA) ,初始值均为零
  • 当某一位第一次出现1时,FA的该位值为1
  • 当想通位第二次出现1时,FA该位值为0,SA该位值为1
  • 当想通位第三次出现1时,FA该位值为0,SA该位值为0

这样,出现三次的数值都会被过滤掉,而只出现一次的数值会留在FA中。
假设 E 为元素某位的值,我们需要有 newFA 和 newSA 来临时储存新的值,按照结果推到出关于 newFA 的如下表格:

SA/E0/00/11/01/1
FA=00100
FA=110xx

我们需要由这个表格推导出 newFA 与 FA、SA、E的位运算关系:

  • SA 为0时,缩小了取值范围,并覆盖了 newFA==1 的范围,即得出一个 & 运算因子 ~SA
  • 当 FA/E 为 0/1 或 1/0 时,进一步缩小了取值范围,且恰好与所有 newFA==1 的范围匹配,得出 & 运算因子 FA^E

所以newFA 与 FA、SA、E的位运算关系为 newFA = ~SA & (FA^E)

newSA 的如下表格:

FA/E0/00/11/01/1
SA=00001
SA=110xx

由这个表格推导 newSA 与 FA、SA、E的位运算关系:

  • SA 与 E 相反时,缩小了取值范围,并覆盖了 newSA==1 的范围,即得出一个 & 运算因子 SA^E
  • 当 FA/E 为 0/0 或 1/1 时,进一步缩小了取值范围,且恰好与所有 newSA==1 的范围匹配,得出 & 运算因子 ~(FA^E)

所以newFA 与 FA、SA、E的位运算关系为 newSA = (SA^E) & ~(FA^E)
之后再把 FA = newFA 和 SA = newSA 即可。
PS:推导的原则基本上就是不断缩小取值范围,直至完全匹配,然后用 & 连接运算因子。

实现代码

Swift code:

let arr = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4];
var FA = 0
var SA = 0
var newFA = 0
var newSA = 0
for E in arr{
newFA = ~SA & (FA^E)
newSA = (SA^E) & ~(FA^E)
FA = newFA
SA = newSA
}
print(FA)
//4
print(SA)
//0

PS:若是查找该数组中仅有的重复两次的元素,SA即是
代码地址:https://github.com/sinianshou/EGSwiftLearning

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值