给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
Method 1:基于哈希表的方法
Code:
class Solution
{
public:
// 基于哈希表的方法
int singleNumber(vector<int> &nums)
{
// map基于红黑树实现,查找的时间复杂度O(n)
// map<int,int> arr;
// unordered_map基于哈希表实现,查找的时间复杂度较低O(1)
unordered_map<int,int> arr;
// 遍历数组
for(int i=0;i<nums.size();i++)
{
// 用哈希表存储每个数组的出现次数
arr[nums[i]]++;
}
// 遍历数组
for(int i=0;i<nums.size();i++)
{
// 找出哈希表中只出现一次的数字
if(arr[nums[i]]==1)
{
// 返回该数字
return nums[i];
}
}
// 没有则返回0
return 0;
}
};
Method 2:基于异或运算的方法
这是我个人感觉很巧妙的一种方法,参考自其他博主的代码。
我们可以发现,在给定的非空整数数组内,元素的出现次数仅有1次/2次。
这个条件是一个突破口,意味着可以使用异或运算来解决这个问题。
首先,异或运算的性质如下:
1. a ⊕ 0 = a
任何数与0进行异或运算,结果都为该数本身。
2. a ⊕ a = 0
任何数与自己做异或运算,结果都为0。
3. a ⊕ b ⊕ a = b ⊕ a ⊕ a = b ⊕ ( a ⊕ a ) = b ⊕ 0 = b
异或运算满足交换律和结合律
根据题目给定的条件和异或运算的性质,我们可以发现:如果对数组中的所有元素进行异或运算,最终的结果必定是那个只出现了一次的数字。
Code:
class Solution
{
public:
// 基于异或运算的方法
int singleNumber(vector<int> &nums)
{
// 保存最终的结果
int result_number=nums[0];
// 遍历数组
for(int i=1;i<nums.size();i++)
{
// 进行异或运算
result_number^=nums[i];
}
// 返回最终的结果
return result_number;
}
};
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/single-number
Reference: