题目描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
题目解析
根据题目描述,由于加上了时间复杂度必须是 O(n),并且空间复杂度为 O(1)的条件,因此不能用排序方法,也不能使用 map 数据结构。那么可以使用位操作的特性来解这个题。
由异或运算的性质(相同为0,不同为1),那么出现两次的元素经过异或运算结果为0,那么数组中所有元素异或运算的结果就是剩下的唯一一个值了。
1 | $arr=array(9,2,2,4,4); |
进阶版
将原题的1个数出现一次改为2个不同的数出现一次,其他条件保持不变
首先通过上面的步骤获得2个不同的数的异或结果,由异或的性质得到这两个数至少有一位是不同的,即一个为0,一个为1。
根据异或的性质,任何一个数字异或他自己都等于0,得到这个数字二进制形式中任意一个为1的位都是我们要找的那个位数。
再然后,以这一位是 1 还是 0 为标准,将数组的 n 个元素分成两部分。
将这一位为 0 的所有元素做异或,得出的数就是只出现一次的数中的一个
将这一位为 1 的所有元素做异或,得出的数就是只出现一次的数中的另一个。
这样就解出题目。忽略寻找不同位的过程,总共遍历数组两次,时间复杂度为 O(n)。
1 | $arr=array(899,2,2,4,4,100); |