LeetCode 136. 只出现一次的数字(易)& 面试题56 - II. 数组中数字出现的次数 II(中)
一个数组,其中N个数出现出现M次,其余数字出现Q次,求出出现M次的N个数字是哪些的题目,都要考虑用位运算来做。
题目
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1: 1
2输入: [2,2,1]
输出: 11
2输入: [4,1,2,1,2]
输出: 4
直觉
哈希表,两次遍历。
第一次遍历,一张哈希表,存储映射关系。 第二次遍历,找到为1的数字。
时间复杂度: \(O(n \times 2)\) ,空间复杂度:\(O(1)\) 。
一次遍历
- 遍历
nums
中的每一个元素。- 如果某个
nums
中的数字是新出现的,则将它添加到列表中。 - 如果某个数字已经在列表中,删除它。
- 如果某个
时间复杂度: \(O(n)\) ,空间复杂度:\(O(N)\) 。
对异或运算符的应用,非常有趣。
1 |
|
时间复杂度: \(O(n)\) ,我们只需要将 nums
中的元素遍历一遍,所以时间复杂度就是 nums
中的元素个数,空间复杂度:\(O(1)\)
代码
哈希表,两次遍历。
1 |
|
一次遍历
1 |
|
对异或运算符的应用
1 |
|
举一反三
137. 只出现一次的数字 II(中)& 面试题56 - II. 数组中数字出现的次数 II(中)
Question
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1: 1
2输入: [2,2,3,2]
输出: 31
2输入: [0,1,0,1,0,1,99]
输出: 99
Intuition
完全不用额外空间,非常难。但是可以做到使用常数级别的空间。
统计各个位上的数字
如下图所示,考虑数字的二进制形式,对于出现三次的数字,各 二进制位出现的次数都是 \(3\) 的倍数。因此,统计所有数字的各二进制位中 \(1\) 的出现次数,并对 \(3\) 求余,结果则为只出现一次的数字。时间复杂度为 \(O(N)\),空间复杂度为 \(O(1)\)。

参考链接
作者:Krahets 链接:https://leetcode-cn.com/problems/single-number-ii/solution/single-number-ii-mo-ni-san-jin-zhi-fa-by-jin407891/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
位运算
为了区分出现一次的数字和出现三次的数字,使用两个位掩码:seen_once 和 seen_twice。 思路是: 仅当 seen_twice 未变时,改变 seen_once。 仅当 seen_once 未变时,改变seen_twice。 时间复杂度为 \(O(N)\),空间复杂度为 \(O(1)\)。

参考链接
作者:LeetCode 链接:https://leetcode-cn.com/problems/single-number-ii/solution/zhi-chu-xian-yi-ci-de-shu-zi-ii-by-leetcode/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Code
- Krahets
1 |
|
- LeetCode
1 |
|
260. 只出现一次的数字 III(中)
Question
给定一个整数数组 nums
,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
示例 :
1 |
|
注意:
- 结果输出的顺序并不重要,对于上面的例子,
[5, 3]
也是正确答案。 - 你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
Intuition
使用异或运算可以帮助我们消除出现两次的数字;我们计算 bitmask ^= x
,则 bitmask
留下的就是出现奇数次的位。

x & (-x)
是保留位中最右边 1
,且将其余的 1
设位 0
的方法。

算法 首先计算 bitmask ^= x
,则 bitmask
不会保留出现两次数字的值,因为相同数字的异或值为 0
。 但是 bitmask
会保留只出现一次的两个数字(x
和 y
)之间的差异。
我们可以直接从
bitmask
中提取 x
和 y
吗?不能,但是我们可以用 bitmask
作为标记来分离 x
和 y
。我们通过 bitmask & (-bitmask)
保留 bitmask
最右边的 1
,这个 1
要么来自 x
,要么来自 y
。

当我们找到了 x
,那么 y = bitmask^x
。 时间复杂度:\(O(N)\) 的时间遍历输入数组。 空间复杂度:\(O(1)\)。
Code
1 |
|
总结
一个数组,其中N个数出现出现M次,其余数字出现Q次,求出出现M次的N个数字是哪些的题目,都要考虑用位运算来做。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!