算法题总结之找到数组中出现次数唯一不同的数字

本文介绍了一种算法问题,即在整型数组中,所有元素出现k次,只有一个元素出现p次(p % k != 0),并提供了详细思路,通过位运算找到这个单独的元素。算法时间复杂度为O(n * logk),空间复杂度为O(logk)。
摘要由CSDN通过智能技术生成

题型

我们的问题是:“给出一个整型数组,每个元素都出现 k (k>1)次,只有一个元素出现 p 次(p >= 1,p % k != 0)。找到这个单独的元素。”

详细思路

如其他人指出的,为了执行位运算操作,我们应该考虑整数在计算机中是如何表示的——通过位。首先我们考虑一位。假设我们有一个一位数字(只能为0或者1)组成的数组,我们可以计算数组中1出现的次数,每次计算的1的次数达到一个特定的值,也就是k时,计算归0并且重新开始(以防你混淆,这里的k就是题目中的k)。要记录我们计算了多少1,就需要一个计数器。假设计数器有m位,二进制表示为:xm, …, x1(从最高位到最低位)。我们至少可以推断出计数器的下面四个特性:

1、计数器有一个初始值, 一般就是0;
2、对于数组的每次输入,如果我们遇到0,计数器保持不变;
3、对于数组的每次输入,如果我们遇到1,计数器应该增加1;
4、要覆盖k次,我们需要 2^m >= k,也就是 m >= logk。

关键部分是:在我们浏览数组时如何改变计数器中的每一位(x1到xm)。注意我们可以用位运算操作。要保证第二个特性,回想一下那个位运算操作不会在另一个运算元是0时改变本身?对,就是 x = x | 0 和 x = x ^ 0。

好,我们现在有表达式 x = x | i 或者 x = x ^ i,i 就是数组中的元素。哪个更好?我们现在还不知道。所以我们先做一下实际的计算:

一开始,计数器的所有位都初始化位0,比如,xm = 0, …, x1 = 0。因为我们要选择位操作来保证在遇到0时计数器的所有位保持不变,直到我们在数组中遇到了1。遇到第一个1之后,我们得到:xm = 0, …, x1 = 1。然后我们继续下去直到遇到第二个1,这时我们就有:xm = 0, …, x2 = 1, x1 = 0。注意x1从1变为0了。对于 x1 = x1 | i,在第二次计算时,x1还会是1。所以很明显我们应该用 x1 = x1 ^ i。那 x2, …, xm 呢?关键是要找到 x2, …, xm 什么时候会变。拿 x2 做例子。如果我们遇到 1 并且需要改变 x2 的值,那我们做这个操作时 x1 一定是什么?答案是:x1 必须是1,否则我们不应该改变 x2 ,而是应该将 x1 从 0 改为 1。所以只有当 x1 和 i 都为 1 时才应该改变 x2,写成公式就是 x2 = x2 ^ (x1 & i)。类似的 xm 也只会在 xm-1, …, x1 和 i 都为 1 时改变:xm = xm ^ (xm-1 & … &a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值