Easy
题目描述
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量级别的额外空间。
示例 1:
输入:nums = [2,2,1]
输出:1
示例 2:
输入:nums = [4,1,2,1,2]
输出:4
示例 3:
输入:nums = [1]
输出:1
提示:
1 <= nums.length <= 3 * 10^4-3 * 10^4 <= nums[i] <= 3 * 10^4- 除了某个元素只出现一次以外,其余每个元素均出现两次。
解题思路
这道题有多种解法,但考虑到时间复杂度 O(n) 和空间复杂度 O(1) 的要求,异或运算是最优解。
方法一:异或运算(推荐)
异或运算有以下重要性质:
a ^ a = 0(相同数字异或为0)a ^ 0 = a(任何数与0异或为自身)- 异或运算满足交换律和结合律
由于数组中除了一个数字出现一次外,其他数字都出现两次,我们可以将所有数字进行异或运算。相同的数字异或后会变成0,最终剩下的就是只出现一次的数字。
方法二:哈希表 使用哈希表统计每个数字的出现次数,然后找到出现次数为1的数字。但这种方法空间复杂度为 O(n),不满足题目要求。
方法三:数学方法
利用 2 * (所有不同数字的和) - 数组总和 = 目标数字 的性质,但需要额外的集合存储,空间复杂度也不是常量级。
代码实现
class Solution {
public:
int singleNumber(vector<int>& nums) {
int result = 0;
for (int num : nums) {
result ^= num;
}
return result;
}
};
class Solution:
def singleNumber(self, nums: List[int]) -> int:
result = 0
for num in nums:
result ^= num
return result
public class Solution {
public int SingleNumber(int[] nums) {
int result = 0;
foreach (int num in nums) {
result ^= num;
}
return result;
}
}
var singleNumber = function(nums) {
let result = 0;
for (let num of nums) {
result ^= num;
}
return result;
};
复杂度分析
| 复杂度类型 | 异或运算解法 | 哈希表解法 |
|---|---|---|
| 时间复杂度 | O(n) | O(n) |
| 空间复杂度 | O(1) | O(n) |
其中 n 为数组长度。异或运算解法满足题目要求的常量空间复杂度,是最优解。
相关题目
. Single Number II (Medium)
. Single Number III (Medium)
. Missing Number (Easy)
. Find the Duplicate Number (Medium)
. Find the Difference (Easy)